2013-08-29 50 views
2

我想在彙編程序中做一個簡單的程序,但我不明白爲什麼,我得到一個錯誤。 我有一臺運行Ubuntu 12.04的64位機器,和彙編編譯器一樣「as」。 我的目標僅僅是在屏幕上打印字符串「你好」。在彙編和字符串中的分段錯誤

我寫了這個:

#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 

你覺得爲什麼出現這種情況?任何想法?

+0

使用gdb來逐步執行代碼和調試問題。 –

+2

由於您正在編寫64位代碼,請考慮切換到使用「syscall」指令而不是「int $ 0x80」。 – Michael

+0

如果將'.section .data'更改爲'.section .text',會發生什麼? – AlexJ136

回答

1

這裏是修復:

#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 
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不歸。閱讀您平臺的調用約定。

+0

我剛試過,但是錯誤一直在出來。我發現它在執行ret語句時發生。 – badnack

+1

你的應用程序需要調用'sys_exit',而不是'ret'urn。 –