汇编 Win32 _printf 代码崩溃

标签 assembly nasm

我是 NASM 汇编程序的新手,并尝试编写自己的汇编代码。编译后,我没有收到任何错误,但在运行时,代码崩溃了。调试时,代码似乎在推送或 _printf 调用时崩溃。

我对代码进行了注释,使其更具可读性。

global _main
extern _printf  

section .text
_main:
    jp _loop ;jump to loop

_loop: 
    mov ebx, [a] ;move double word 'a' into register ebx
    inc ebx ;increment register ebx
    mov [a], ebx ;move contents of ebx into double word 'a'
    add ebx, '0' ;add char 0 (0x30)
    push ebx ;push ascii character on to stack
    push format ;push format string on to stack
    call _printf ;call print function
    cmp dword [a], 10 ;compare if value of a is equal to 10
    jne _loop ;loop if not equal to 10
    ret ;return if equal to 10

a:
    dd 0 ;initialize dword as 0

format:
    db "%i", 0 ;format string for printf

提前致谢!我希望这不是太菜鸟。

最佳答案

我尝试自己编译并运行您的代码(可惜不是在 Windows 上;谁说程序集不可移植?),并且它不是在 call _printfpush 上崩溃的> 行,但位于 mov [a], ebx 上。 .text 段的权限是读取和执行,但不是写入。 a 位于 .text 中,并且 mov [a], ebx 尝试写入 a,因此它会尝试写入不可写的部分,并且程序因一般保护错误而崩溃。解决这个问题的方法是将 a 放在不同的部分中,例如.data.

这应该可以解决您的(第一)问题,但您还应该了解两件事:

  1. 您将 jp _loop 作为 _main 的第一条指令。如果设置了奇偶校验标志,则会跳转到_loop。我不认为你真的想测试奇偶校验标志;在这种情况下,它要么跳转到那里,要么测试失败并且无论如何都会落入 _loop 。您可以执行显式 jmp,但这实际上没有必要。如果我是你,我会完全省略该指令,以便 _main_loop 重合。

  2. 我相信 _printf 使用 C 调用约定,其中调用者负责弹出参数(与 Windows API 函数使用的 stdcall 不同);你把很多东西压入堆栈,却从不弹出它们。这意味着迭代次数越多,使用的堆栈内存就越多。这似乎不是你想要的。此外,您稍后ret,由于您同时推送了内容,因此不会返回到正确的位置,因为堆栈顶部不是返回地址。您需要在调用 _printf 后显式弹出或调整堆栈指针:

    add esp, 8
    

    或者:

    1. 在循环之前,保留适当数量的堆栈空间:

      sub esp, 8
      
    2. 循环结束后,释放堆栈空间:

      add esp, 8
      
    3. 不要压入参数,而是修改堆栈上已有的数据:

      mov [esp+4], ebx
      mov [esp], format
      

关于汇编 Win32 _printf 代码崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31757526/

相关文章:

c++ - 为什么 g++ 使用 movabs 和一个奇怪的常量来进行简单的归约?

assembly - nasm:重定位被截断以适合:R_386_PC8 针对 `*UND*'

bash - 如何让 nasm 在 MacOS 的终端中作为命令工作?

assembly - 向BX寄存器写入值对ES寄存器有影响吗?

assembly - 使用 intel2gas 的 NASM 到 GAS 语法

assembly - 当前程序状态寄存器异常模式

assembly - 汇编中的局部变量存储分配

c - 自动 assembly 循环级分析

linux - 打印第二个命令行参数

macos - 如何在 Mac OS X 上创建 ELF 可执行文件?