2015-11-30 2 views
0

J'essaie d'adapter du code que nous avons développé en classe et j'ai un problème.Le calcul de la moyenne des notes dans le langage d'assemblage se bloque

Voici le code que nous avons développé en classe - prenez 10 nombres, faites la moyenne.

include irvine32.inc 
    Title GetTen 
    .data 
    inprompt db "Enter a number:",0 
    sumMsg db "The sum of your numbers is ",0 
    avgMsg db "The average of your number is ",0 
    nums db 10 dup(0) ;duplicate nums 10 times for indirect 
    sum db 0 
    divisor db 0 
    .code 

    main proc 

    call getValues 
    call sumValues 
    call calcAvg 

    exit 
    jmp ENDITALL 
    ;SUM 10 VALUES 
    sumValues proc 
    mov ebx,offset nums 
    mov ecx, lengthof nums 
    sub eax,eax 
    SumLoop: 
    add al,[ebx] 
    add ebx,1 
    loop SumLoop 
    mov sum,al 
    mov edx,offset sumMsg 
    call WriteString 
    call WriteInt 

    call crlf 
    ret 
    sumValues endp 

    ;READ 10 Numbers in proc 
    getValues PROC 
    mov ebx, offset nums 
    mov ecx, lengthof nums 
    InLoop: 
    mov edx, offset inprompt 
    call WriteString 
    call ReadInt 
    call crlf 
    mov [ebx],al 
    add ebx,1 ;add one to advance the nums array 
    loop InLoop 
    ret 
    getValues endp 

    ;--------Calculate the average 
    calcAvg proc 
    mov ebx, lengthof nums 
    mov divisor,bl 
    call dumpregs 
    div bl ;the first operand is always eax 
    ;call dumpregs 
    mov edx, offset avgMsg 
    call writestring 
    movsx eax,al 
    ;call dumpregs 
    call writeInt 
    ret 
    calcAvg endp 


    ENDITALL: 

    main endp 
    end main 

Ce code fonctionne très bien. J'ai besoin de l'adapter dans un calculateur de notes (mis en dix notes numériques, les moyennes, puis comparez la moyenne à certaines valeurs pré-conservées pour attribuer une note numérique.) Toutes les choses de base, sauf AL n'aime pas les chiffres comme 100 beaucoup - si j'entre, par exemple, 5 100 et 5 80, il me dit que la somme des nombres est 132 et la moyenne est 13.

OK, donc j'ai essayé AH et EAX à la place de AL, en supposant que Il n'y avait pas assez de place à AL. Voici ce code.

include irvine32.inc 
    Title GradeAverage 
    .data 
    inprompt db "Enter a grade:",0 
    sumMsg db "The sum of your numbers is ",0 
    avgMsg db "The average of your grade is ",0 
    nums dd 10 dup(0) ;duplicate nums 10 times for indirect 
    sum dd 0 
    divisor dd 0 
    .code 

    main proc 

    call getValues 
    call sumValues 
    call calcAvg 

    exit 
    jmp ENDITALL 
    ;SUM 10 VALUES 
    sumValues proc 
    mov ebx,offset nums 
    mov ecx, lengthof nums 
    sub eax,eax 
    SumLoop: 
    add eax,[ebx] 
    add ebx,1 
    loop SumLoop 
    ;mov sum,eax ;I shouldn't even need this anymore since we're using all the  same size. 
    mov edx,offset sumMsg 
    call WriteString 
    call WriteInt 

    call crlf 
    ret 
    sumValues endp 

    ;READ 10 Numbers in proc 
    getValues PROC 
    mov ebx, offset nums 
    mov ecx, lengthof nums 
    InLoop: 
    mov edx, offset inprompt 
    call WriteString 
    call ReadInt 
    call crlf 
    mov [ebx],eax 
    add ebx,1 ;add one to advance the nums array 
    loop InLoop 
    ret 
    getValues endp 

    ;--------Calculate the average 
    calcAvg proc 
    mov esi, lengthof nums 
    mov divisor,esi 
    call dumpregs 
    div esi ;the first operand is always eax 
;call dumpregs 
    mov edx, offset avgMsg 
    call writestring 
    ;movsx eax,eax 
    ;call dumpregs 
    call writeInt 
    ret 
    calcAvg endp 


    ENDITALL: 

    main endp 
    end main 

Ce code se bloque. Il faudra prendre les chiffres, et si je mets, dis 100 5 fois et 50 5 fois, il me dit que la somme est de -42041476 et ensuite se bloque.

C'est probablement quelque chose de vraiment basique, mais je suis à court de ressources. Qu'est-ce que je fais mal ici?

+0

La chose habituelle ... oublier que 'div esi' utilisera' edx' comme les 32 premiers bits du dividende. Bien que cela n'affecte pas la sommation. 'ajouter ebx, 1' est faux aussi, vous devez' ajouter ebx, 4' puisque chaque entier est de 4 octets. – Jester

Répondre

0

Vous avez au moins un bug et quelques problèmes conceptuels.

Concept: EAX est le nom d'un registre 32 bits; les 16 bits inférieurs de ce registre sont appelés AX. En AX, les 8 bits inférieurs sont appelés AL et le plus haut - AH.

Concept: une instruction N-bit qui implique la lecture/écriture de N bits dans la mémoire. Lorsque vous utilisez AL, vous pouvez lire/écrire 8 bits, et lorsque vous utilisez EAX, vous lisez/écrivez 32 bits.

.... donc votre boucle principale de somme a un bug, il lit 32 bits de mémoire à chaque fois:

SumLoop: 
    add eax,[ebx] 
    add ebx,1 
    loop SumLoop 

Disons que vous avez octets [1,2,3,4] à [EBX ] La première boucle ajoute 1234H à EAX, les boucles suivantes sont inconnues car la mémoire que vous lisez est hors des limites de votre tableau. L'accident peut être dû à ceci ou quelque chose d'entièrement différent.

Si vos données sont des octets, vous pouvez lire les un par un:

xor edx, edx 
SumLoop: 
    mov dl,[ebx] 
    add eax, edx 
    inc ebx 
    loop SumLoop 

Et dans votre proc moyenne, vous avez div esi mais avant votre div EDX devez être remis à zéro parce que vous êtes division [EDX , EAX] Numéro de 64 bits à ESI. Vous devez ajouter xor dx,dx avant cette instruction