簡體   English   中英

NASM子例程和分段錯誤

[英]NASM subroutines and segmentation fault

我一直在嘗試使用NASM和匯編語言,因此,我對子例程在該語言中的工作方式有一個基本的了解。 但是,我的問題是,如何在同一過程中捆綁不同的標簽。 例如,在我在SO中找到的以下代碼中:

;-----------------------------------------------
;SECTION .DATA
;Instantiated variables/Constants
;-----------------------------------------------
section .data

result:     db "The smallest number is: " , 0x0a
result_len:     equ $-result

nl:     db "   ", 0x0a
nl_len  equ $-nl

    matrix: dw  25, 24, 23, 22, 21
            dw  20, 19, 18, 17, 16 
            dw  15, 14, 13, 12, 11 
            dw  10,  9,  8,  7,  6
            dw   5,  4,  3,  2,  1


;-----------------------------------------------
;SECTION .BSS
;Non initialized variables
;-----------------------------------------------
section .bss


;-----------------------------------------------
;SECTION .TEXT
;Code
;-----------------------------------------------
section .text
global _start 

_start: 

mov edi, 0
mov esi, 0
mov ecx, 12         

outerLoop:
cmp edi, 50                  ;each element is 2 bytes (2 ascii characters)
ja  endloop                  ;we need 50 because it's 5 elements per row
mov esi, 0                   ;and 5 rows
innerLoop:
cmp esi, 5                   ;Compare esi(inner loop index) to 5
jae innerEnd                 ;jump if it reached the end of the row
mov ax, [matrix + edi + esi*2]
cmp ax, cx
jg  biggerThan
mov cx, ax
biggerThan:
inc esi
jmp innerLoop
innerEnd:
add edi, 10                  ;row has been complete, go to next
jmp outerLoop

endloop:
push    ecx

mov eax, 4
mov ebx, 1
mov ecx, result
mov edx, result_len
int 0x80

mov eax, 4
mov ebx, 1
mov ecx, esp
add [ecx], DWORD 30h
mov edx, 2
int 0x80

; display new line
mov eax, 4
mov ebx, 1
mov ecx, nl
mov edx, nl_len
int 0x80

exit:
mov eax, 1          ;eax contains 1 so quit
mov ebx, 0
int 0x80

是否可以在單個過程中將innerLoop,outerLoop,bigThan,innerEnd等捆綁在一起,然后像這樣調用該過程:

;-----------------------------------------------
;SECTION .DATA
;Instantiated variables/Constants
;-----------------------------------------------
section .data

result:     db "The smallest number is: " , 0x0a
result_len:     equ $-result

nl:     db "   ", 0x0a
nl_len  equ $-nl

    matrix: dw  25, 24, 23, 22, 21
            dw  20, 19, 18, 17, 16 
            dw  15, 14, 13, 12, 11 
            dw  10,  9,  8,  7,  6
            dw   5,  4,  3,  2,  1


;-----------------------------------------------
;SECTION .BSS
;Non initialized variables
;-----------------------------------------------
section .bss


;-----------------------------------------------
;SECTION .TEXT
;Code
;-----------------------------------------------
section .text
global _start 

_start: 

mov edi, 0
mov esi, 0
mov ecx, 12         

call findSmallestNumber


findSmallestNumber:
outerLoop:
cmp edi, 50                  ;each element is 2 bytes (2 ascii characters)
ja  endloop                  ;we need 50 because it's 5 elements per row
mov esi, 0                   ;and 5 rows
innerLoop:
cmp esi, 5                   ;Compare esi(inner loop index) to 5
jae innerEnd                 ;jump if it reached the end of the row
mov ax, [matrix + edi + esi*2]
cmp ax, cx
jg  biggerThan
mov cx, ax
biggerThan:
inc esi
jmp innerLoop
innerEnd:
add edi, 10                  ;row has been complete, go to next
jmp outerLoop

endloop:
push    ecx


ret

mov eax, 4
mov ebx, 1
mov ecx, result
mov edx, result_len
int 0x80

mov eax, 4
mov ebx, 1
mov ecx, esp
add [ecx], DWORD 30h
mov edx, 2
int 0x80

; display new line
mov eax, 4
mov ebx, 1
mov ecx, nl
mov edx, nl_len
int 0x80



exit:
mov eax, 1          ;eax contains 1 so quit
mov ebx, 0
int 0x80

這樣做會始終導致Linux中的分段錯誤錯誤,因此我嘗試執行此操作的方式肯定存在問題。 任何幫助將不勝感激!

至少有兩個問題:

  1. push ecx不應成為子例程的一部分,因為該子例程已經在主程序中進行了編碼。 它設置緩沖區以通過write系統調用進行打印。 其位置由mov ecx, esp行使用。 請注意, ret從堆棧中彈出一個地址,然后返回堆棧。 因此,在這種情況下,它將彈出您的ecx值,並嘗試將其用作將導致故障的返回地址。
  2. 當子例程返回時,cpu在call指令之后繼續執行代碼。 在您的情況下,這意味着它將再次進入findSmallestNumber子例程(因為它直接在call ),但是這次堆棧上沒有返回地址。 因此,即使固定了#1點, ret仍然會發生故障。 解決方案是將子例程移出直接執行路徑。 在進行退出調用之后,將整個子例程放在代碼的末尾。

PS:如果您打算使用匯編代碼,則應該學習使用調試器,這樣您就可以單步執行代碼並查看問題所在。 您可能還想閱讀有關通常使用的調用約定的信息 如果您想與其他代碼交互,則將需要此代碼。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM