使用fscanf进行装配时的EOF

时间:2013-12-22 12:32:11

标签: assembly x86 eof scanf

我正在尝试使用fscanf读取文件的内容并将其写入另一个文件。一切顺利,直到它到达文件的末尾,当它继续读取最后一个单词并继续将其打印到我的输出文件。

如何检测 eof ?我知道我可以使用带有fread的二进制阅读来做到这一点,但有没有办法用fscanf执行此操作?

.386
.model flat, stdcall

.code  
start:  
push offset read_mode       ;open the file  
push offset textFile_name   ;  
call fopen                  ;  
add esp, 8                  ;  
mov esi, eax                ;  


push offset write_mode      ;create the file
push offset dictFile_name   ;
call fopen                  ;
add esp, 8                  ;
mov edi, eax                ;


Read:  
push offset fileContent     ;read from file  
push offset formatRead  ;  
push esi                    ;  
call fscanf                 ;  
add esp, 12                 ;  



push offset fileContent     ;write to file
push offset formatWrite             ;
push edi                    ;
call fprintf                ;
add esp, 12                 ;

loop Read



push esi                    ;close files
call fclose                 ;
add esp, 4                  ;
push edi                    ;
call fclose                 ;
add esp, 4                  ;

push 0
call exit
end start

1 个答案:

答案 0 :(得分:1)

为什么不检查fscanf的返回值???到达文件末尾时返回EOFEOF通常为-1,所以(由于你没有标记你的汇编程序,我将使用NASM格式作为例子。)....

.Read:  
    push    ebx
    push    fmtstr
    push    esi
    call    fscanf
    add     esp, 4 * 3
    test    eax, eax
    js      .NoMore

    push    ebx
    push    fmtstr
    push    ebp
    call    fprintf
    add     esp, 4 * 3
    jmp     .Read
.NoMore:

...

extern fopen, fscanf, fprintf, fclose, fread
extern fseek, fwrite, ftell, rewind, malloc
extern free, exit, stdout

%define SEEK_END 2

global main

section .data
read_mode       db  "r", 0
write_mode      db  "w", 0
textFile_name   db  "in.txt",0
dictFile_name   db  "out.txt", 0
fmtstr          db  "%s",10 , 0

section .text
main:

    push    read_mode
    push    textFile_name 
    call    fopen
    add     esp, 4 * 2
    mov     esi, eax

    push    SEEK_END
    push    0
    push    eax
    call    fseek
    add     esp, 4 * 3

    push    esi
    call    ftell
    add     esp, 4 * 1  
    mov     edi, eax

    push    eax
    call    malloc
    add     esp, 4 * 1
    mov     ebx, eax

    push    esi
    call    rewind
    add     esp, 4 * 1

    push    write_mode
    push    dictFile_name
    call    fopen
    add     esp, 4 * 2
    mov     ebp, eax

.Read:  
    push    ebx
    push    fmtstr
    push    esi
    call    fscanf
    add     esp, 4 * 3
    test    eax, eax
    js      .NoMore

    push    ebx
    push    fmtstr
    push    ebp
    call    fprintf
    add     esp, 4 * 3
    jmp     .Read

.NoMore:        
    push    esi
    call    fclose
    add     esp, 4 * 1

    push    ebp
    call    fclose
    add     esp, 4 * 1

    push    ebx
    call    free
    add     esp, 4 * 1  

    push    0
    call    exit
    add     esp, 4 * 1

仅使用freadfwrite会不会更容易?

section .text
main:

    push    read_mode
    push    textFile_name 
    call    fopen
    add     esp, 4 * 2
    mov     esi, eax

    push    SEEK_END
    push    0
    push    eax
    call    fseek
    add     esp, 4 * 3

    push    esi
    call    ftell
    add     esp, 4 * 1  
    mov     edi, eax

    push    eax
    call    malloc
    add     esp, 4 * 1
    mov     ebx, eax

    push    esi
    call    rewind
    add     esp, 4 * 1

    push    esi
    push    edi
    push    1
    push    ebx
    call    fread
    add     esp, 4 * 4

    push    esi
    call    fclose
    add     esp, 4 * 1

    push    write_mode
    push    dictFile_name
    call    fopen
    add     esp, 4 * 2
    mov     esi, eax

    push    eax
    push    edi
    push    1
    push    ebx
    call    fwrite
    add     esp, 4 * 4

    push    esi
    call    fclose
    add     esp, 4 * 1

    push    ebx
    call    free
    add     esp, 4 * 1  

    push    0
    call    exit
    add     esp, 4 * 1

错误检查是故意遗漏的,当然应该/会检查这些电话的返回值......