2016-07-15 15 views
2

因此,我遇到了主線27上的段錯誤,並且在我的子程序調用後,我的%rax保持在值0,當它不應該是。程序集x86 - 字符串段錯誤次數/計數子程序沒有保存返回值的頻率

我想弄清楚我的子程序沒有正確地做什麼 - 我假設它與我的字節比較,因爲我還不太熟悉它們。

我在printf調用中也得到了主程序第27行的段錯誤。我在這裏假設printf函數是預定義的 - 儘管我想我可能也需要在這裏創建一個printf子程序。

.text 
    .globl FREQ 



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

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

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

donefreq: 
    ret 

主要

   .data 
string:   .string "This course is about encoding numbers and instructions into binary sequences and designing digital systems to process them." 
endofstring: .space 8 
msg:   .string "%c occurs %d times \n" 

       .text 
       .global main 

main: 
    sub  $8,%rsp     #stack alignment 
    mov  $string,%rsi   #rsi = string storage 
    mov  $0x61, %r8    #storage of a 
    mov  $0x65, %r9    #storage of e 
    mov  $0x69, %r10    #storage of i 
    mov  $0x6F, %r11    #storage of o 
    mov  $0x75, %r12    #storage of u 


#Case A 
    mov  %r8,%rcx 
    mov  $0, %rax    #initialize count to 0 
    call FREQ     #Generate %rax value for count 
    mov  %rax, %rdx    #2nd argument for print function - number of 
    mov  $msg, %rdi    #1st argument for print function - format for print function 
    mov  %r8, %rsp   #3rd argument for print function - char 

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


#Case E 
    mov  %r9,%rcx 
    mov  $0, %rax    #initialize count to 0 
    call FREQ 
    mov  $msg, %rdi    #1st argument for print function - format for print function 
    mov  %r9, %rsp   #3rd argument for print function - char 
    mov  %rax, %rdx    #2nd argument for print function - number of 
    call printf     #print the frequency value of the ch in string 

#Case O 
    mov  %r10,%rcx 
    mov  $0, %rax    #initialize count to 0 
    call FREQ 
    mov  $msg, %rdi    #1st argument for print function - format for print function 
    mov  %r10, %rsp   #3rd argument for print function - char 
    mov  %rax, %rdx    #2nd argument for print function - number of 
    call printf     #print the frequency value of the ch in string 

#Case I 
    mov  %r11,%rcx 
    mov  $0, %rax    #initialize count to 0 
    call FREQ 
    mov  $msg, %rdi    #1st argument for print function - format for print function 
    mov  %r11, %rsp   #3rd argument for print function - char 
    mov  %rax, %rdx    #2nd argument for print function - number of 
    call printf     #print the frequency value of the ch in string 
#Case U 
    mov  %r12,%rcx 
    mov  $0, %rax    #initialize count to 0 
    call FREQ 
    mov  $msg, %rdi    #1st argument for print function - format for print function 
    mov  %r12, %rsp   #3rd argument for print function - char 
    mov  %rax, %rdx    #2nd argument for print function - number of 
    call printf     #print the frequency value of the ch in string 

    jmp done 




done: 
    add  $8, %rsp    #reset stack alignment 
    ret 

則計算在句子中的每個元音的數量 - 輸出在打印聲明字符數。

+0

'mov%r9,%rsp'是錯誤的推測。你想要'mov%r9,%rsi'在那裏和所有其他地方。你也有其他的錯誤,但這是你問的:) – Jester

+0

這絕對是一個錯字:(哦,天哪。謝謝。希望其他錯誤將很容易修復! –

+0

@Jester嘿小丑,你會碰巧知道我如何使用GDB檢查子程序中的值?我使用'gcc -g -o runtest main.s count.s'進行編譯,然後使用'gdb runtest'在調用線路之前和之後的線路中斷,但是當我得到到'call count'這行就跳過它,結果表明子程序中斷只是'break count.s:1'。謝謝! –

回答

1

至少有以下問題(我假設這是X86-64):

  1. 第二個參數必須在%rsi通過。
  2. 第三個參數必須在%rdx中傳遞。
  3. 對於printf,您需要將%rax設置爲所用向量寄存器的數量(在您的情況下爲0),例如,與xor %rax, %rax

printf是一個帶可變參數列表的C函數。調用這樣的功能的公約可以在ABI 3.5.7節中找到:

當考慮可變參數的函數被調用時,%rax必須被設置爲傳遞到在載體中的功能浮點參數的總數寄存器。

+0

%al對printf函數做了什麼? –

+0

@Egyptian_Coder不知怎的,我記得它錯了。 ABI表示%rax必須爲0.請參閱我的編輯。 – ead

+1

@Egyptian_Coder:這是傳遞給可變參數函數的向量參數的個數(如'printf')。我在這個回答中討論這個需求:http://stackoverflow.com/a/38335743/3857942 –

相關問題