2016-07-15 30 views
-2

Ich versuche zu debuggen, warum ich einen segfault in meinem Unterprogramm bekomme.Assembly - Segfault mit Subprogramm

Es passiert auf der Ret-Zeile am Ende des Unterprogramms - als einmal das 0x00 Byte am Ende des Satzes erreichen.

Main:

   .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 

Subprogram:

.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 

nicht sicher, warum dies geschieht. - Ich wünschte, Debugging gab ein bisschen mehr Info :(

Hat jemand eine Idee, warum dies geschieht? Ich folgte genau den Umriss meiner Notizen für die aufgerufene Funktion, so dass ich bin nicht in der Lage, wo das Problem in der Angerufene ist

+0

Ihr Unterprogramm fügt zu _RSP_ hinzu, so dass die Rücksendeadresse zu dem Zeitpunkt, an dem es an die "ret" gelangt, nein ist länger an der richtigen Stelle auf dem Stapel und "ret" wird abstürzen, um zu einem halb zufälligen Speicherort zurückzukehren. –

+0

'mov $ string,% rsp' das bin ich auch sehr schlecht. Sie müssen lesen, wie der Stapel funktioniert und Parameter übergeben. Ihr Code weist erhebliche Probleme auf. –

+0

Um dem entgegenzuwirken, sollte ich die Zeiten zählen, in denen ich RSP erhöht habe, und dann die Anzahl der RSP, bevor ich zurückkomme? –

Antwort

3

Sie nicht %rsp als Zeiger auf der Zeichenfolge verwendet werden soll. Sie sind die Absenderadresse im Stapel korrumpieren, damit Ihre ret Anweisung versucht, einige falsche Adresse zu springen. verwenden Sie %rsi oder einen anderen Mehrzweckregister. die Stack Pointer ist kein Register, das Sie verwenden können, wie Sie möchten

+0

Danke - das hat die Verwirrung, die ich hatte, geklärt. Sehr geschätzt - Ich habe auf $ rsi für String-Speicherung umgestellt, wie vom großartigen @Jester vorgeschlagen. Ty alle. –