【问题标题】:itoa implementation crashing?itoa 实现崩溃了?
【发布时间】:2013-08-16 20:44:22
【问题描述】:

我正在尝试在汇编(网络汇编器)中实现 atoi。我已经通过使用调试器检查寄存器值来验证我的方法是有效的。问题是应用程序在即将退出时会崩溃。我担心我的程序以某种方式破坏了堆栈。我正在链接 GCC 标准库以允许使用 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

这里是堆栈转储:

例外:在 eip=00402005 处的 STATUS_ACCESS_VIOLATION eax=00000000 ebx=00000000 ecx=20000038 edx=61185C40 esi=612A3A7C edi=0022CD84 ebp=0022ACF8 esp=0022AC20 程序=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 真的不再那么重要了,它只是显示了一个不正确的值。

【问题讨论】:

  • 请注意,上面的代码并没有崩溃。 OP问了一个问题,然后在他们得到答案后改变了问题。这使得搜索网络的人更难找到类似问题的解决方案。

标签: c assembly nasm


【解决方案1】:

我不熟悉您的平台,但我希望您需要通过在调用 printf() 后弹出推送的值来恢复堆栈。

由于printf() 不知道要传递多少个参数,所以它无法恢复堆栈。您的代码推送永远不会弹出的参数。因此,当您的过程返回时,它会从压入堆栈的数据中获取返回地址,这些数据不会指向有效代码。那将是您的访问违规。

【讨论】:

  • 我正在使用 Windows 和 Cygwin 作为我的工具链,抱歉,因为我忘了提及 :) 我只是尝试弹出这两个值,但没有帮助。
  • 您确实没有提供足够的信息。您应该将一小段代码放在原始问题中,而不需要导航到另一个站点。现在我只能猜测你的新代码是什么样子的。另外,我不知道您正在使用多少位。指向_str 的指针有多少字节?
  • 我正在使用 Pastebin,因为当我尝试将代码放入代码标签时,SO 总是会搞砸。这是一个 32 位程序。我搞砸了你关于弹出这两个值的建议。现在已正确完成,程序不再崩溃,但仍显示不正确的值 (52515049)。我现在将编辑问题。
  • 是的,我看到您的代码存在许多问题。请不要编辑问题。请将我的回答标记为已接受,如果您有新问题,请创建一个新问题。
  • 你显示的数字正是你告诉它的!您可能想尝试告诉_printf 显示一个字符。然后你应该会看到“4321”...如预期的那样。
猜你喜欢
  • 1970-01-01
  • 2012-01-25
  • 2013-04-10
  • 1970-01-01
  • 2022-08-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多