我的程序集实现中的分段错误

问题描述 投票:1回答:1

我是汇编语言编程的新手,在这里我试图从我的汇编代码中调用C标准库函数put,但我不断得到segmentaion错误。请帮忙;操作系统:LINUX 16.04汇编程序:nasm机器:intel x86 - 64bit

;comiple and build:
;                   nasm -f elf64 -F stabs helloc.asm
;                   gcc -o helloC helloC.o
[SECTION .data]
   msg: db "Hello C",0
[SECTION .bss]

[SECTION .text] 
 extern puts

 global main 
 main:
  push rsp

  push dword msg
  call puts
  add rsp,4

  pop rsp
  ret
c linux assembly x86-64 calling-convention
1个回答
1
投票

解释Comments更多,从x86调用约定和你的代码开始。

x86 Calling Convention

在x86中,参数位于堆栈中。所以基本上你的函数调用是x86方式。例如,如果您为x86构建代码,

[SECTION .data]
   msg: db "Hello C",0
[SECTION .bss]

[SECTION .text] 
 extern puts

 global main 
 main:
  push ebp
  mov ebp, esp
  and esp, 0xfffffff0
  sub esp, 0x10

  mov DWORD PTR [esp], msg
  call puts


  mov esp, ebp
  pop ebp
  ret

它可能工作正常。

x86-64 Calling Convention

主要区别在于两件事。

  • 当然,使用8个字节来表示地址
  • 使用6个registeres(rdi,rsi,rdx,rcx,r8,r9)代表前6个参数(rest位于堆栈中)

首先,您应该将push dword msg更改为mov rdi, msg,并且不要在调用后清理堆栈(因为您没有将任何内容推送到堆栈)

改变后:

[SECTION .data]
   msg: db "Hello C",0
[SECTION .bss]

[SECTION .text] 
 extern puts

 global main 
 main:
  push rbp
  mov rbp, rsp
  and rsp, 0xfffffffffffffff0

  mov rdi, msg
  call puts


  mov rsp, rbp
  pop rbp
  ret

编辑:来自System V ABI,对于调用指令堆栈应该是16字节对齐。因此push rbp对齐,但使用不正确。要改变它,为x86和x86-64制作堆栈保存逻辑。

© www.soinside.com 2019 - 2024. All rights reserved.