当我运行程序时,我遇到了段错误。该程序包括两个数字之间的简单加法,将值存储在变量中,然后打印出来以进行系统调用。
这是我称之为的代码:
section .bss
res: resq 1
fout: resq 1
section .data
msg dq 'Hello, world!', 0xa ;string to be printed
len equ $ - msg ;length of the string
filename dq 'hello.txt'
section .text
global _start: ;must be declared for linker (ld)
_start: ;tells linker entry point
mov rcx,5
mov rdx,4
call sum
mov [res],rax
mov rdx,1 ;message length
mov rcx,res ;message to write
mov rbx,1 ;file descriptor (stdout)
mov rax,4 ;system call number (sys_write)
syscall ;call kernel
mov rax,1 ;system call number (sys_exit)
syscall ;call kernel
sum:
mov rax,rcx
add rax,rdx
add rax,'0'
ret
调试信息:
(gdb) n
sum () at Hello.asm:41
41 mov rax,rcx
(gdb) n
42 add rax,rdx
(gdb) n
43 add rax,'0'
(gdb) n
sum () at Hello.asm:44
44 ret
(gdb) n
0x0000000000000001 in ?? ()
(gdb) n
No se pueden encontrar límites en la función actual
(gdb) quit
结果是分割错误。
答案 0 :(得分:2)
您尝试将res
中的8个字节存储在mov [res],rax
中,尽管仅为res
分配了1个字节。尽管这是错误的,但这不是导致程序失败的问题。写mov [res], al
来解决这个问题。
真正的问题是您的系统电话号码错误。您为i386 Linux使用了系统呼叫号码,但是这些是具有不同号码的amd64系统呼叫。有关正确的系统调用号码,请参考asm/unistd_64.h
中的值。对于您的示例,正确的数字是1
的{{1}}和sys_write
的{{1}}。修正这些数字可使您的程序不再崩溃,但仍无法正常工作。
您还需要修复使用的寄存器。在amd64上系统调用的调用约定与i386不同。您无需将参数放在ebx,ecx等中。而是使用60
,sys_exit
,rdi
,rsi
,rdx
和{ this answer中概述的{1}}。解决此问题可使您的程序最终运行。