2016-07-15 1 views
2

Donc je cours dans un segfault sur la ligne 27 de main et après mon appel de sous-programme mon% rax reste à la valeur 0 quand il ne devrait pas être. J'essaie de comprendre ce que mon sous-programme ne fait pas correctement - je suppose que c'est avec mes comparaisons d'octets que je ne suis pas trop familier avec eux pour le moment.Assembly x86 - Fréquence du sous-programme segfault/count non enregistré valeur de retour

Je reçois également une erreur de segmentation sur la ligne 27 du programme principal avec l'appel printf. Je suppose ici que la fonction printf est prédéfinie - bien que je pense que je pourrais avoir besoin de faire un sous-programme printf ici aussi.

Sous

.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 

principale

   .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 

Le programme compte le nombre de chaque voyelle dans la phrase - le nombre de sorties ce caractère dans une déclaration d'impression.

+0

'mov% r9,% rsp' est probablement une faute de frappe. Vous voulez 'mov% r9,% rsi' là et à tous les autres endroits. Vous avez d'autres erreurs aussi, mais c'est celui que vous avez demandé à propos de :) – Jester

+0

C'est certainement une faute de frappe :(Oh mon dieu merci .. Espérons que les autres erreurs seront des correctifs faciles! –

+0

@Jester Hey Jester, auriez-vous à connaître comment je peux vérifier les valeurs dans un sous-programme en utilisant GDB? Je compile avec 'gcc -g -o runtest main.s count.s' puis,' gdb runtest' avec des sauts sur les lignes avant et après la ligne d'appel mais quand je reçois à la ligne 'call count' il saute juste au-dessus de lui.S'il sort son juste' break count.s: 1' pour les ruptures de sous-programme.Merci! –

Répondre

1

Il y a au moins les points suivants (je suppose qu'il est pour x86-64):

  1. Le second argument doit être transmis à %rsi.
  2. Le troisième argument doit être passé dans %rdx.
  3. Pour printf, vous devez définir %rax sur le nombre de registres vectoriels utilisés (dans votre cas 0), par ex. avec xor %rax, %rax.

printf est une fonction C avec liste d'arguments variable. La convention d'appeler cette fonction se trouve dans ABI section 3.5.7:

Lorsqu'une fonction prise de variables arguments est appelée, %rax doit être réglé sur le nombre total de paramètres à virgule flottante transmis à la fonction dans le vecteur registres.

+0

Que fait% al pour la fonction printf? –

+0

@Egyptian_Coder Quelque part je me suis souvenu mal. L'ABI indique que% rax doit être 0. voir ma modification. – ead

+1

@Egyptian_Coder: C'est le nombre d'arguments vectoriels transmis à une fonction variadique (comme 'printf'). Je discute de cette exigence dans cette réponse SO: http://stackoverflow.com/a/38335743/3857942 –