i386和x86-64内存堆栈之间的区别

时间:2017-01-17 14:35:39

标签: gcc assembly x86 nasm

在我的Ubuntu机器上尝试使用NASM和GCC制作一个非常小的程序时,我发现了一些奇怪的东西。

以下代码在64位NASM和GCC下编译良好:

   global  main
   extern  puts

section .text
   main:
     push    rax
     mov rdi, message
     call puts
     jmp exit
  exit:
    ;return stack memory
    pop rax
    ret
  message:
    db "Hello from NASM!", 0

但是当尝试在32位NASM和GCC下编译相同的代码(仅更改寄存器)时,它将导致分段错误和/或随机字符。为什么会这样?与i386相比,x64架构在将内存存储到堆栈方面有不同的方式吗?如果是这样,如何防止这种行为?

1 个答案:

答案 0 :(得分:3)

在32位模式下,大多数调用约定(cdeclstdcall等...)期望将参数压入堆栈,而不是寄存器,与64位模式不同,您还需要在调用puts后调整堆栈指针,因此您需要执行以下操作:

lea edx, @message
push edx
call puts
add esp, 4

使程序在32位模式下产生相同的输出。我可能没有正确的NASM语法,因为我通常在MASM和GAS中编写汇编代码。