2016-07-15 2 views
-2

サブプログラムにセグメンテーションが表示される理由をデバッグしようとしています。アセンブリ - セグメンテーションとサブプログラム

サブプログラムの最後のret行で発生します.1回は、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 

わかりません。 - 私はデバッグがもう少し情報を与えたらいいと思っています:(

なぜこのようなことが起こるのか、誰にもわかりますか?私は、問題のどこにあるのかを知りたいので、あなたの文字列へのポインタとして%rspを使用しないでください。あなたは、スタック内のリターンアドレスを破損している、あなたのret命令は、いくつかの偽のアドレスにジャンプしようとするので、呼び出し先

+0

あなたのサブプログラムは_RSP_に追加を続けますので、 'ret'になるまでに戻りアドレスはnoですスタックの適切な場所でもっと長く、 'ret'はいくつかのセミランダムメモリ位置に戻ることを試みるとクラッシュします。 –

+0

'mov $ string、%rsp'これは非常に悪いです。スタックの動作とパラメータの受け渡しについては、読んでおく必要があります。あなたのコードには重大な問題があります。 –

+0

これに対処するには、RSPを増やした後、RSPからカウントして戻ってくる回数をカウントしておく必要がありますか? –

答えて

3

である。%rsiまたは別の汎用レジスタを使用してください。スタックポインターはあなたが望むように使用できるレジスタではありません

+0

ありがとう - これは私が持っていた混乱を解消しました。すべて。 –

関連する問題