汇编中的C函数调用问题

C function calling problems in assembly

section .data
text db 'Put a number',10,0
scanform db '%d'
number dw 0

section .text
extern printf,scanf

global main
main:
push rbp
mov rbp,rsp
push rdi
push rsi
push rbx

mov rdi,text
mov rax,0
call printf

mov rsi,number
mov rdi,scanform
mov rax,0
call scanf

pop rbx
pop rsi
pop rdi
ret

这是我的代码,我整天都在写其他代码,我对这些没有问题,但现在当我调用 scanf 时,写入程序接收到信号 SIGSEV、段错误...在不同文件中指定第一行和最后一行。我不明白这条消息有人可以帮助我吗?

您有以下问题:

  1. 您忘记了 pop rbp
  2. 您未对齐需要 16 字节对齐的堆栈。
  3. 您没有以零终止您的格式字符串(感谢 Paul 指出这一点)。
  4. 您使用 %d 写入一个 4 字节整数,但您只使用 dw 分配了 2 个字节。
  5. 建议将整数对齐到 4 个字节。

可能的固定版本:

section .data
number dd 0
text db 'Put a number',10,0
scanform db '%d', 0

section .text
extern printf,scanf

global main
main:
push rbp
mov rbp,rsp
push rdi
push rsi
push rbx
push rbx ; for alignment

mov rdi,text
mov rax,0
call printf

mov rsi,number
mov rdi,scanform
mov rax,0
call scanf

pop rbx
pop rbx
pop rsi
pop rdi
pop rbp
ret

由于rsirdi是调用者保存的寄存器,rbx没有被触及,所以可以简化代码。我也改为 xor 归零和 rip-relative 寻址如下:

section .data
number dd 0
text db 'Put a number',10,0
scanform db '%d', 0

section .text
extern printf,scanf

global main
main:
push rbp

lea rdi, [rel text]
xor eax, eax
call printf

lea rsi, [rel number]
lea rdi, [rel scanform]
xor eax, eax
call scanf

pop rbp
ret