2016-07-15 8 views
2

Итак, я столкнулся с segfault в строке 27 основного и после моего вызова подпрограммы мой% rax остается на значении 0, когда этого не должно быть.Сборка x86 - Частота строки segfault/count подпрограммы не сохраняет возвращаемое значение

Я пытаюсь выяснить, что моя подпрограмма не работает правильно. Я принимаю его с моими байтовыми сравнениями, поскольку я еще не слишком знаком с ними.

Я также получаю segfault в строке 27 основной программы с вызовом printf. Я предполагаю, что функция printf предопределена - хотя я думаю, что мне также понадобится сделать подпрограмму printf.

Sub

.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 Hey 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 с переменным списком аргументов. Конвенции вызвать такую ​​функцию можно найти в разделе 3.5.7 ABI:

Когда функция принимает переменные-аргументы называется, %rax должен быть установлен на общее число параметров с плавающей запятой, переданных функцией в векторе регистры.

+0

Что делает% al для функции printf? –

+0

@Egyptian_Coder Как-то я вспомнил это неправильно. ABI говорит, что% rax должно быть 0. см. Мое редактирование. – ead

+1

@Egyptian_Coder: Это число векторных аргументов, передаваемых переменной функции (например, 'printf'). Я обсуждаю это требование в этом SO-ответе: http://stackoverflow.com/a/38335743/3857942 –

 Смежные вопросы

  • Нет связанных вопросов^_^