2016-07-15 64 views
-2

我想調試爲什麼我在我的子程序中得到一個段錯誤。大會 - Segfault與子程序

它發生在子程序末尾的ret線上 - 就像在句子末尾0x00字節一樣。

主營:

   .data 
string:   .string "aaaaaaaaaaa" 
endofstring: .space 8 
msg:   .string "%c occurs %d times \n" 

       .text 
       .global main 

main: 

    mov  $string,%rsi   #rsi = string storage 
    mov  $0x61, %ah    #storage of a 
    mov  $0x65, %al    #storage of e 
    mov  $0x69, %bh    #storage of i 
    mov  $0x6F, %bl    #storage of o 
    mov  $0x75, %ch    #storage of u 


#Case A 
    mov  %ah,%cl     #1 byte register for cmp later on. 
    mov  $0, %rax    #initialize count to 0 
    call FREQ     #Generate %rax value for 


    mov  %rax, %rdx    #count for printf (2nd argument) 
    mov  $msg, %rdi    #format for printf(1st argument) 
    mov  %r8, %rsi    #ch for printf (3rd argument) 

    xor  %rax, %rax    #reset %rax for printf output 

    call printf     #print the frequency value of the ch in string 


#Case E 
    mov  %al,%cl 
    mov  $0, %rax    #initialize count to 0 
    call FREQ 

    mov  %rax, %rdx    #count for printf (2nd argument) 
    mov  $msg, %rdi    #format for printf(1st argument) 
    mov  %r8, %rsi    #ch for printf (3rd argument) 

    xor  %rax, %rax    #reset %rax for printf output 

    call printf     #print the frequency value of the ch in string 

#Case O 
    mov  %bh,%cl 
    mov  $0, %rax    #initialize count to 0 
    call FREQ 

    mov  %rax, %rdx    #count for printf (2nd argument) 
    mov  $msg, %rdi    #format for printf(1st argument) 
    mov  %r8, %rsi    #ch for printf (3rd argument) 

    xor  %rax, %rax    #reset %rax for printf output 

    call printf     #print the frequency value of the ch in string 

#Case I 
    mov  %bl,%cl 
    mov  $0, %rax    #initialize count to 0 
    call FREQ 

    mov  %rax, %rdx    #count for printf (2nd argument) 
    mov  $msg, %rdi    #format for printf(1st argument) 
    mov  %r8, %rsi    #ch for printf (3rd argument) 

    xor  %rax, %rax    #reset %rax for printf output 

    call printf     #print the frequency value of the ch in string 
#Case U 
    mov  %ch,%cl 
    mov  $0, %rax    #initialize count to 0 
    call FREQ 

    mov  %rax, %rdx    #count for printf (2nd argument) 
    mov  $msg, %rdi    #format for printf(1st argument) 
    mov  %r8, %rsi    #ch for printf (3rd argument) 

    xor  %rax, %rax    #reset %rax for printf output 

    call printf     #print the frequency value of the ch in string 

    jmp done 


done: 

    ret 

子程序:

.text 
    .globl FREQ 



FREQ: 
    #subprogram body 
Start: 
    cmpb $0,8(%rsi)    #check for end of the string 
    je  donefreq 

loopfreq: 
    cmp  %cl, 8(%rsi)   #compare first string char with vowel 
    je  incrementstring   #if equal - jump to increment_string 
    add  $1, %rsi    #if not - increment string 
    jmp  Start     #jump to loop to check for end of string status/next char 

incrementstring: 
    add  $1, %rsi    #increment to next string character 
    add  $1, %rax    #add 1 to frequency of character 
    jmp  Start 

donefreq: 
    ret 

不知道爲什麼會這樣。 - 我希望調試給了一些更多的信息:(

有沒有人有一個想法,爲什麼會發生這種情況?我完全按照我的筆記的大綱爲被調用函數,所以我不知道問題在哪裏在被叫

+0

你的子程序不斷添加到_RSP_,所以當它到達'ret'時,返回地址是no在堆棧上適當的位置更長,'ret'會試圖返回到一些半隨機內存位置。 –

+0

'mov $ string,%rsp'這個我也很不好。您需要閱讀關於堆棧如何工作和參數傳遞的信息。你的代碼有重大問題。 –

+0

因此,爲了解決這個問題,我應該保持在增加RSP的次數,然後在返回之前從RSP中扣除那個計數? –

回答

3

你不應該使用%rsp爲指針,以你的字符串,你是在棧破壞返回地址,以便您ret指令試圖跳轉到一些假地址。使用%rsi或其他通用寄存器。該堆棧指針並不是一個你可以隨意使用的寄存器

+0

謝謝 - 這清理了我的困惑。非常感謝 - 我已經切換到使用$ rsi作爲字符串存儲的建議由偉大的@Jester Ty所有。 –