【发布时间】:2016-03-21 07:13:01
【问题描述】:
这个汇编程序是一个 Fizz 游戏。它应该遵循儿童计数游戏 Fizz 的规则:它应该从 1 到 100 打印,并且每当数字可以被 5 整除或包含数字 5 时,将数字替换为单词“Fizz”。
我目前遇到了这个程序的问题。程序运行,但输出为: 数字 = 1 分段错误(核心转储) 如果有人可以帮助我,我将不胜感激。谢谢
enter cextern printf
section .data
fmt: db "number = %d", 10, 0 ; printf format string
fmt2: db " %s",10,0
fmt3: db " %s ", 10, 0
section .text
global main
main:
push ebx ; EBX is callee saved so we need to save it so that it
; it can be restored when we RETurn from main
xor ecx,ecx ; ebx = 0 (counter)
L1:
inc ecx
xor eax,eax
mov eax,ecx
xor ebx,ebx
xor edx,edx
mov ebx,5
idiv ebx
cmp edx,0
jz Fizz
push ecx ; 2nd parameter is our number to print
push fmt ; 1st parameter is the address of the format string
call printf
;add sp, 8 ; We pushed 8 bytes prior to printf call, we must adjust the stack
; by effectively removing those bytes.
; counter += 1
cmp ecx,100
jle L1 ; If counter is <= 100 go back and print again
jmp end
Fizz:
mov ebx,0x4669
mov eax, 0x7A7A
push ebx
push eax
push fmt2
call printf
pop eax
pop ebx
jmp L1
end:
pop ebx ; Restore EBX before exiting main per calling convention
ret ; RETurn from main will cause program to gracefully exit
; because we are linked to the C runtime code and main was
; called by that C runtime code when our program started.ode here
【问题讨论】:
-
你试过在调试器中运行它并查看它崩溃的地方吗?
-
关于这个looks familiar
-
@micheal Petch,是的,它在 0x080482 处崩溃?? ()。当我完成信息寄存器时,这就是它给我的东西:eax 0x0 0 ECX 0x1 1 EDX 0x1 1 EBX 0x5 5 ESP 0xFFFFD810 0xFFFFD810 EBP 0x0 0x0 ESI 0x1 1 EDI 0xF7FB3000 -134533120 EIP 0xF7FF06C1 0xF7FF06C1 <_dl_runtime_resolve> EFLAGS 0x202 [如果] cs 0x23 35 ss 0x2b 43 ds 0x2b 43 es 0x2b 43 fs 0x0 0 gs 0x63 99 (gdb)
-
ECX 将被 printf 调用丢弃,您注释掉的添加
esp, 8将不会在您的main结束后顺利结束函数执行ret。不确定您要对使用fmt2的 printf 的调用做什么。 EAX 将被视为一个指针,但您已使用垃圾 (0x7a7a) 地址加载它,因此 printf 可能会失败(或崩溃) -
为什么要在
eax和ebx中放置字符文字?只需在数据部分声明字符串"Fizz",10,0并使用它。