2014-04-14 99 views
1

我得到了一個分段錯誤,下面的彙編代碼只是打印出一條消息,儘管打印是由一個單獨的函數處理的,所以我很確定我沒有在堆棧中分配正確的空間消息和長度。分段錯誤彙編

下面是代碼:

section .data 
    print_msg:  DB "H", 10, 0 
    len:   equ $-print_msg 
    print_msg2:  DB "BYE WORLD", 10, 0 
    len2:   equ $-print_msg2 


section .text 

    global main 

main: 
    push ebp 
    mov ebp, esp 

    push DWORD len 
    push print_msg 
    call _write 

    push DWORD len2 
    push print_msg2 
    call _write 

    leave 
    ret 

_write: 
    push ebp 
    mov ebp, esp 

    push ebx 
    mov eax, 4 
    mov ebx, 1 
    mov ecx, [ebp+8] 
    mov edx, [ebp+12] 
    int 80h 
    pop ebx 

    leave 
    ret 
+0

不會'push print_msg'推一個指針,而不是字符? – James

+0

@詹姆斯:的確如此。另一個問題是'_write'中的'ebp'相對偏移量是錯誤的(舊的'ebp'將位於'[ebp + 0]',並且返回地址位於'[ebp + 4]')。 – Michael

+0

@James Oh等指針只有4個字節? – user28130

回答

0
  1. 你並不需要分配在堆棧上的任何空間,因爲push會爲你做的。
  2. push DWORD [len]是錯誤的,因爲它試圖取消引用len這只是一個數字。
  3. mov ecx, [ebp+2]mov edx, [ebp+6]正在使用錯誤的偏移量,它們應該分別爲+8+12。從ebp棧佈局是:saved_ebpreturn addressarg1arg2(各4字節)

像這樣:

section .data 
    print_msg:  DB "H", 10, 0 
    len:   equ $-print_msg 

section .text 

    global main 
main: 
    push ebp 
    mov ebp, esp 
    push DWORD len 
    push print_msg 
    call _write 
    leave 
    ret 

_write: 
    push ebp 
    mov ebp, esp 
    mov eax, 4 
    mov ebx, 1 
    mov ecx, [ebp+8] 
    mov edx, [ebp+12] 
    int 80h 
    leave 
    ret 

PS:C調用約定強制要求,你應該保持ebx,所以_write函數應保存並恢復它。

+0

非常感謝你,我明白了,我一直在學習下面的教程,我們需要物理地分配物品的空間,以便將它們推入堆棧。 – user28130

+0

哦,所以我應該在堆棧上推ebx,然後在函數外部恢復它。 – user28130

+0

你可以分配空間,但是你應該使用'mov'來寫入這個空間而不是'push'。確保爲每個參數分配4個字節。爲了保存/恢復'ebx',你應該在'_write'內部'push'和'pop',我建議分別在'mov ebp,esp'和'leave'之前。 – Jester