itoa实施崩溃?
我正在尝试在汇编中实现atoi(网络汇编程序)。 我已通过使用调试器检查寄存器值验证了我的方法是有效的。 问题是应用程序即将退出时会崩溃。 恐怕我的程序不知何故破坏了堆栈。 我链接到GCC stdlib以允许使用printf函数。 我注意到它突变了引起意外行为的寄存器(对我没有认识到的值进行了广泛的迭代),但是我通过将EAX的值存储在EBX中(未由printf修改),然后在函数调用后恢复该值来解决此问题。 这就是为什么我已经能够确认程序现在按照它应该通过单步执行算法的行为并确认程序崩溃,因为它即将终止。 代码如下:
global _main
extern _printf
section .data
_str: db "%d", 0
section .text
_main:
mov eax, 1234
mov ebx, 10
call _itoa
_terminate:
ret
_itoa:
test eax, eax
jz _terminate
xor edx, edx
div ebx
add edx, 30h
push eax
push edx
push _str
call _printf
add esp, 8
pop eax
jmp _itoa
这里是stackdump:
例外:eip = 00402005时的STATUS_ACCESS_VIOLATION eax = 00000000 ebx = 00000000 ecx = 20000038 edx = 61185C40 esi = 612A3A7C edi = 0022CD84 ebp = 0022ACF8 esp = 0022AC20 program = C: Cygwin home Benjamin nasm itoa.exe,pid 3556 ,线程主cs = 001B ds = 0023 es = 0023 fs = 003B gs = 0000 ss = 0023堆栈跟踪:帧函数参数0022ACF8 00402005(00000000,0022CD84,61007120,00000000)堆栈跟踪结束
编辑:请注意,stackdump真的不再相关了,因为该程序不再崩溃,它只是显示一个不正确的值。
我不熟悉你的平台,但我希望你需要在调用printf()
之后弹出推入的值来恢复堆栈。
由于printf()
不知道将传递多少个参数,因此无法恢复堆栈。 您的代码推送永远不会弹出的参数。 所以当你的过程返回时,它会从堆栈中的数据获取返回地址,这些数据不会指向有效的代码。 这将是您的访问违规。