【发布时间】:2015-11-10 04:03:42
【问题描述】:
使用 NASM,我试图打开一个文本文件并打印文本文件的每个字符。问题是,fgetc 不断返回 -1。
extern printf
extern fopen
extern fgetc
extern fclose
SECTION .data ; Data section, initialized variables
p1_fmt: db 0xA, "blah", 0xA, 0xA, 0
p2_fmt: db 0xA, "Opening: stuff.txt", 0xA, 0xA, 0
p3_fmt: db 0xA, "Closing.", 0xA, 0xA, 0
result_fmt: db 0xA, "search results: a=%d, e=%d, i=%d, o=%d, u=%d", 0
p5_fmt: db 0xA, "debug", 0
p6_fmt: db 0xA, "character: %d", 0xA, 0
file_name: db "stuff.txt", 0
file_mode: db "r", 0
SECTION .bss ; Data section, uninitialized variables
num_a resd 0
num_e resd 0
num_i resd 0
num_o resd 0
num_u resd 0
SECTION .text ; Code section.
global main ; the standard gcc entry point
main: ; the program label for the entry point
push p1_fmt
call printf
add esp, 4
push p2_fmt
call printf
add esp, 4
;push file_mode
;push file_name
mov DWORD [esp], file_name
mov DWORD [esp + 4], file_mode
call fopen
add esp, 8
push eax ; push file pointer on stack.
character:
call fgetc ; an int is in eax now
mov ebx, eax ; ebx holds this int too
; this continuously print a -1...
push ebx
push p6_fmt
call printf
add esp, 8
cmp ebx, 0
je no_characters_left
; need to loop thru all the characters.
cmp ebx, 97
je vowel_a
cmp ebx, 101
je vowel_e
cmp ebx, 105
je vowel_i
cmp ebx, 111
je vowel_o
cmp ebx, 117
je vowel_u
jne character
vowel_a:
mov eax, num_a
inc eax
mov [num_a], eax
jmp character
vowel_e:
mov eax, num_e
inc eax
mov [num_e], eax
jmp character
vowel_i:
mov eax, num_i
inc eax
mov [num_i], eax
jmp character
vowel_o:
mov eax, num_o
inc eax
mov [num_o], eax
jmp character
vowel_u:
mov eax, num_u
inc eax
mov [num_u], eax
jmp character
no_characters_left:
call fclose
add esp, 4 ; remove file pointer off the stack
push p5_fmt
call printf
add esp, 4
mov eax, 0 ; normal, no error, return value
ret ; return
【问题讨论】:
-
首先,你确定你系统上的调用约定是
cdecl,你还记得sub esp, 8,然后再把参数放到堆栈上吗? -
1.是的。我正在使用 ubuntu 32 位。 2.是的,这里是完整的代码:hastebin.com/ijuyuvipay.avrasm
-
你是编译成32位还是64位?这些指令对 64 位系统完全有效,但您不会为 x86-64 调用约定生成正确的指令。
-
我将其编译为 32 位我相信:
nasm -f elf test.asmgcc test.o -masm=intel -o test -
cmp ebx, 0在检查是否还有剩余字符时看起来很可疑。 ASCII 0 (nul) 仍然是有效字符。当遇到 EOF 时,libc通常会从fgetc返回 -1(在 Linux 上)。
标签: assembly x86 std nasm calling-convention