assembly和string中的分割错误

我想在汇编程序中做一个简单的程序,但我不明白为什么,我得到了一个错误。 我有一个运行Ubuntu 12.04的64位机器,和汇编编译器一样。 我的目标仅仅是在屏幕上打印string“你好”。

我写了这个:

#print.s .section .data .globl StringToPrint StringToPrint: .asciz "Hello" .globl _start _start: movq $4, %rax movq $1, %rbx movq $StringToPrint, %rcx movq $5, %rdx int $0x80 _done: ret 

但是,这就是我得到的:

 $ as print.s -o print.o $ ld print.o -o print $ ./print Hello[1] 10679 segmentation fault (core dumped) ./print 

你为什么认为这发生? 任何想法?

这是修复:

 #print.s .section .data .globl StringToPrint StringToPrint: .asciz "Hello" .globl _start _start: movl $5, %edx # string length movl $StringToPrint, %ecx # pointer to string to write movl $1, %ebx # file handle (stdout) movl $4, %eax # system call number (sys_write) int $0x80 # Passes control to interrupt vector #sys_exit (return_code) movl $1, %eax #System call number 1: exit() movl $0, %ebx #Exits with exit status 0 int $0x80 #Passes control to interrupt vector 

正如迈克尔已经表示,你需要调用sys_exit来避免分段错误。

编辑
这里很好的提到int 0x80调用32位系统调用。
在x64系统上对系统调用使用int 0x80用于向后兼容以允许运行32位应用程序。

在64位系统上使用syscall指令是正确的。
这是一个工作版本:

 .section .data StringToPrint: .asciz "Hello" .section .text .globl _start _start: movq $1, %rax # sys_write movq $1, %rdi # stdout movq $StringToPrint, %rsi # pointer to string to write movq $5, %rdx # string length syscall movq $60, %rax # sys_exit movq $0, %rdi # exit code syscall 

在Linux和其他操作系统中,调用约定与32位和64位应用程序不同。 另外,对于Linux系统调用号码也是不同的。 这就是你在Linux amd64中调用write系统调用的方法:

 ; sys_write(stdout, message, length) mov rax, 1 ; sys_write mov rdi, 1 ; stdout mov rsi, message ; message address mov rdx, length ; message string length syscall 

此外,您的应用程序需要调用sys_exit来终止,而不是使用ret返回。 阅读您平台的调用约定。