如何用 fread 填充 malloc 的缓冲区?
How to fill malloc'd buffer with fread?
对于长代码表示歉意,但是就像汇编一样:
SECTION .text ; code
extern _fclose
extern _fopen
extern _fread
extern _fseek
extern _ftell
extern _malloc
extern _printf
global _main
_main:
; stash base stack pointer
push ebp
mov ebp, esp
push DWORD fname
push DWORD mopf
push DWORD mcls
call _printf
add esp, 12 ; clean up stack use
; open file
push DWORD fread
push DWORD fname
call _fopen
add esp, 8
cmp eax, 0
jnz .valid
push DWORD mfnf
push DWORD mopf
jmp .error
.valid:
mov [fh], eax
; output result
push DWORD [fh]
push DWORD mopf
push DWORD mret
call _printf
add esp, 12
push DWORD [fh]
push DWORD mskf
push DWORD mcld
call _printf
add esp, 12
; C:
; fseek(fp, 0L, SEEK_END); ; set up constants: SEEK_END, SEEK_SET, etc.
push DWORD [SEEK_END]
push DWORD 0 ; 0L
push DWORD [fh] ; f_hndl
call _fseek ; ret [eax]: 0 okay; otherwise 1
add esp, 12 ; reset stack pointer
cmp eax, 0
je .success
push DWORD mske
push DWORD mskf
jmp .error
.success:
; output result
push DWORD eax
push DWORD mskf
push DWORD mret
call _printf
add esp, 12
; C:
; sz = ftell(fp); ; result to eax
push DWORD [fh]
call _ftell
add esp, 4
mov [fsz], eax
; output result
push DWORD [fsz]
push DWORD mszf
push DWORD mcld
call _printf
add esp, 12
; allocate buffer
; C:
; p* = malloc(size)
push DWORD [fsz]
call _malloc
add esp, 4
mov DWORD[buffer], eax
; read file
; size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
push DWORD [fh]
push DWORD 1
push DWORD [fsz]
push DWORD [buffer]
call _fread
add esp, 16
push DWORD eax
push DWORD mrdf
push DWORD mcld
call _printf
add esp, 12
jmp .done
.error:
push DWORD merr
call _printf
add esp, 12
.done:
push DWORD [fh]
call _fclose
push DWORD eax
push DWORD mclf
push DWORD mcld
call _printf
add esp, 16
; restore base stack pointer
mov esp, ebp
pop ebp
ret
SECTION .bss ; uninitialized data
fh: resd 1
fsz: resd 1
buffer: resb 20
当前输出:
[FILE] call [open]: d:\asmplus\tsources\s1.txt
[FILE] ret [open]: 2002397536
[FILE] call [seek]: 2002397536
[FILE] ret [seek]: 0
[FILE] call [size]: 6
[FILE] call [read]: 0
[FILE] call [close]: 0
根据@Michael 的回复更正了输出
我添加了一个额外的输出(上面的代码中没有显示)产生以下内容:
[FILE] ret [╨9=]: 6
... 在 fread
调用之后:
push DWORD [fsz]
push DWORD [buffer]
push DWORD mret
call _printf
add esp, 12
显然[fsz]
从正确的值6(字节)变成了[buffer]
(20字节)的长度加2.
根据定义 size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
我希望 EAX
包含读取的字节数。
相关片段:
; allocate buffer
; C:
; p* = malloc(size)
push DWORD [fsz]
call _malloc
add esp, 4
mov DWORD[bfr], eax
; read file
; size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
push DWORD [fh] ; FILE* stream (file handle)
push DWORD 1 ; size_t nmemb
push DWORD [fsz] ; size_t size
push DWORD [buffer] ; void* ptr (buffer previously malloc'd)
call _fread
add esp, 16
我从 description here 假设:
Parameters:
* ptr -- This is the pointer to a block of memory with a minimum size
of size*nmemb bytes
* size -- This is the size in bytes of each element to be read.
* nmemb -- This is the number of elements, each one with a size of size bytes.
* stream -- This is the pointer to a FILE object that specifies an input stream.
... size
将是 1 个字节(字符大小)并且 nmemb
将是缓冲区 malloc 的大小。
首先调用和分配 malloc
缓冲区,然后调用 fread
填充缓冲区,我做错了什么?
更新
添加代码以返回源文件的开头后,我正在读取字节。然而,现在似乎有一些问题引发了一些问题。这是输出:
[FILE] call [read]: 1
[FILE] ret [1 + 2;r]: 6
文件 s1.txt 包含 1 + 2;
,这是在第 2 行正确报告的 6 个字节。但是 fread
显然报告说它只读取了 1 个字节?我应该在 fread
的调用中使用 fsz
+ 1 来摆脱 [1 + 2;r]
中的 r
吗?
从 the documentation 到 printf
:
Return Value
On success, the total number of characters written is returned.
基于此,此代码不正确:
call _printf
add esp, 12
mov [fsz], eax
您在 fsz
中保存的是 printf
中的 return 值,即字符串 "[FILE] call [size]: 6"
.
的长度
看起来你在阅读文件之前并没有回到文件的开头。因此,如果您尝试从末尾读取,您将获得 0 个字节。
即。添加:
push DWORD 0 ; SEEK_SET = 0
push DWORD 0 ; 0L
push DWORD [fh] ; f_hndl
call _fseek ; ret [eax]: 0 okay; otherwise 1
add esp, 12 ; reset stack pointer
The file s1.txt contains 1 + 2; which is 6 bytes correctly reported on
the 2nd line. But fread is apparently reporting that it only read 1
byte?
不,fread 报告它读取了 1 个 6 字节的结构。你可能想要这个:
push DWORD [fh]
push DWORD [fsz]
push DWORD 1 ; Note.. swapped!!!
push DWORD [buffer]
call _fread
add esp, 16
对于缓冲区末尾的字节 -- 您正在从文件中读取 6 个字节,但 printf 需要一个以空字符结尾的字符串。如果你想解决这个问题,分配一个额外的字节 space,并在调用 printf 之前将最后一个字节设置为 '\0'。
对于长代码表示歉意,但是就像汇编一样:
SECTION .text ; code
extern _fclose
extern _fopen
extern _fread
extern _fseek
extern _ftell
extern _malloc
extern _printf
global _main
_main:
; stash base stack pointer
push ebp
mov ebp, esp
push DWORD fname
push DWORD mopf
push DWORD mcls
call _printf
add esp, 12 ; clean up stack use
; open file
push DWORD fread
push DWORD fname
call _fopen
add esp, 8
cmp eax, 0
jnz .valid
push DWORD mfnf
push DWORD mopf
jmp .error
.valid:
mov [fh], eax
; output result
push DWORD [fh]
push DWORD mopf
push DWORD mret
call _printf
add esp, 12
push DWORD [fh]
push DWORD mskf
push DWORD mcld
call _printf
add esp, 12
; C:
; fseek(fp, 0L, SEEK_END); ; set up constants: SEEK_END, SEEK_SET, etc.
push DWORD [SEEK_END]
push DWORD 0 ; 0L
push DWORD [fh] ; f_hndl
call _fseek ; ret [eax]: 0 okay; otherwise 1
add esp, 12 ; reset stack pointer
cmp eax, 0
je .success
push DWORD mske
push DWORD mskf
jmp .error
.success:
; output result
push DWORD eax
push DWORD mskf
push DWORD mret
call _printf
add esp, 12
; C:
; sz = ftell(fp); ; result to eax
push DWORD [fh]
call _ftell
add esp, 4
mov [fsz], eax
; output result
push DWORD [fsz]
push DWORD mszf
push DWORD mcld
call _printf
add esp, 12
; allocate buffer
; C:
; p* = malloc(size)
push DWORD [fsz]
call _malloc
add esp, 4
mov DWORD[buffer], eax
; read file
; size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
push DWORD [fh]
push DWORD 1
push DWORD [fsz]
push DWORD [buffer]
call _fread
add esp, 16
push DWORD eax
push DWORD mrdf
push DWORD mcld
call _printf
add esp, 12
jmp .done
.error:
push DWORD merr
call _printf
add esp, 12
.done:
push DWORD [fh]
call _fclose
push DWORD eax
push DWORD mclf
push DWORD mcld
call _printf
add esp, 16
; restore base stack pointer
mov esp, ebp
pop ebp
ret
SECTION .bss ; uninitialized data
fh: resd 1
fsz: resd 1
buffer: resb 20
当前输出:
[FILE] call [open]: d:\asmplus\tsources\s1.txt
[FILE] ret [open]: 2002397536
[FILE] call [seek]: 2002397536
[FILE] ret [seek]: 0
[FILE] call [size]: 6
[FILE] call [read]: 0
[FILE] call [close]: 0
根据@Michael 的回复更正了输出
我添加了一个额外的输出(上面的代码中没有显示)产生以下内容:
[FILE] ret [╨9=]: 6
... 在 fread
调用之后:
push DWORD [fsz]
push DWORD [buffer]
push DWORD mret
call _printf
add esp, 12
显然[fsz]
从正确的值6(字节)变成了[buffer]
(20字节)的长度加2.
根据定义 size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
我希望 EAX
包含读取的字节数。
相关片段:
; allocate buffer
; C:
; p* = malloc(size)
push DWORD [fsz]
call _malloc
add esp, 4
mov DWORD[bfr], eax
; read file
; size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
push DWORD [fh] ; FILE* stream (file handle)
push DWORD 1 ; size_t nmemb
push DWORD [fsz] ; size_t size
push DWORD [buffer] ; void* ptr (buffer previously malloc'd)
call _fread
add esp, 16
我从 description here 假设:
Parameters:
* ptr -- This is the pointer to a block of memory with a minimum size of size*nmemb bytes
* size -- This is the size in bytes of each element to be read.
* nmemb -- This is the number of elements, each one with a size of size bytes.
* stream -- This is the pointer to a FILE object that specifies an input stream.
... size
将是 1 个字节(字符大小)并且 nmemb
将是缓冲区 malloc 的大小。
首先调用和分配 malloc
缓冲区,然后调用 fread
填充缓冲区,我做错了什么?
更新
添加代码以返回源文件的开头后,我正在读取字节。然而,现在似乎有一些问题引发了一些问题。这是输出:
[FILE] call [read]: 1
[FILE] ret [1 + 2;r]: 6
文件 s1.txt 包含 1 + 2;
,这是在第 2 行正确报告的 6 个字节。但是 fread
显然报告说它只读取了 1 个字节?我应该在 fread
的调用中使用 fsz
+ 1 来摆脱 [1 + 2;r]
中的 r
吗?
从 the documentation 到 printf
:
Return Value
On success, the total number of characters written is returned.
基于此,此代码不正确:
call _printf
add esp, 12
mov [fsz], eax
您在 fsz
中保存的是 printf
中的 return 值,即字符串 "[FILE] call [size]: 6"
.
看起来你在阅读文件之前并没有回到文件的开头。因此,如果您尝试从末尾读取,您将获得 0 个字节。
即。添加:
push DWORD 0 ; SEEK_SET = 0
push DWORD 0 ; 0L
push DWORD [fh] ; f_hndl
call _fseek ; ret [eax]: 0 okay; otherwise 1
add esp, 12 ; reset stack pointer
The file s1.txt contains 1 + 2; which is 6 bytes correctly reported on the 2nd line. But fread is apparently reporting that it only read 1 byte?
不,fread 报告它读取了 1 个 6 字节的结构。你可能想要这个:
push DWORD [fh]
push DWORD [fsz]
push DWORD 1 ; Note.. swapped!!!
push DWORD [buffer]
call _fread
add esp, 16
对于缓冲区末尾的字节 -- 您正在从文件中读取 6 个字节,但 printf 需要一个以空字符结尾的字符串。如果你想解决这个问题,分配一个额外的字节 space,并在调用 printf 之前将最后一个字节设置为 '\0'。