我的 Assembly 实现中的分段错误
Segmentation fault in my Assembly implementation
我是汇编语言编程的新手,在这里我试图从我的汇编代码中调用 C 标准库函数 puts,但我不断遇到段错误。请帮忙;
操作系统:LINUX 16.04
汇编器:nasm
机器:英特尔 x86 - 64 位
;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
解释更多,从x86调用约定和你的代码开始。
x86 调用约定
在 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 调用约定
主要区别有两点。
- 当然是用8个字节来表示地址
- 使用 6 个寄存器(rdi、rsi、rdx、rcx、r8、r9)来表示前 6 个参数(其余位于堆栈中)
所以首先,您应该将 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
EDIT:来自System V ABI,调用指令堆栈应该是 16 字节对齐的。所以 push rbp
对对齐有影响,但使用目的不正确。要更改它,请为 x86 和 x86-64 制作堆栈保存逻辑。
我是汇编语言编程的新手,在这里我试图从我的汇编代码中调用 C 标准库函数 puts,但我不断遇到段错误。请帮忙; 操作系统:LINUX 16.04 汇编器:nasm 机器:英特尔 x86 - 64 位
;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
解释
x86 调用约定
在 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 调用约定
主要区别有两点。
- 当然是用8个字节来表示地址
- 使用 6 个寄存器(rdi、rsi、rdx、rcx、r8、r9)来表示前 6 个参数(其余位于堆栈中)
所以首先,您应该将 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
EDIT:来自System V ABI,调用指令堆栈应该是 16 字节对齐的。所以 push rbp
对对齐有影响,但使用目的不正确。要更改它,请为 x86 和 x86-64 制作堆栈保存逻辑。