汇编中的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、段错误...在不同文件中指定第一行和最后一行。我不明白这条消息有人可以帮助我吗?
您有以下问题:
- 您忘记了
pop rbp
。
- 您未对齐需要 16 字节对齐的堆栈。
- 您没有以零终止您的格式字符串(感谢 Paul 指出这一点)。
- 您使用
%d
写入一个 4 字节整数,但您只使用 dw
分配了 2 个字节。
- 建议将整数对齐到 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
由于rsi
和rdi
是调用者保存的寄存器,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
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、段错误...在不同文件中指定第一行和最后一行。我不明白这条消息有人可以帮助我吗?
您有以下问题:
- 您忘记了
pop rbp
。 - 您未对齐需要 16 字节对齐的堆栈。
- 您没有以零终止您的格式字符串(感谢 Paul 指出这一点)。
- 您使用
%d
写入一个 4 字节整数,但您只使用dw
分配了 2 个字节。 - 建议将整数对齐到 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
由于rsi
和rdi
是调用者保存的寄存器,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