2

我正在尝试用汇编程序编写一个简单的程序,但我不明白为什么,我出错了。我有一台运行 Ubuntu 12.04 的 64 位机器,并将“as”作为汇编编译器。我的目标只是在屏幕上打印字符串“Hello”。

我写了这个:

#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

你认为为什么会发生这种情况?任何的想法?

4

2 回答 2

2

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

; 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. 阅读您平台的调用约定。

于 2013-08-29T15:21:56.327 回答
2

这是修复:

#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 0x80for syscall 用于向后兼容以允许 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
于 2013-08-29T16:18:55.663 回答