2015-11-30 28 views
0

我正在嘗試修改我們在課堂上開發的一些代碼,並且遇到問題。在彙編語言崩潰中的等級平均值

這裏是我們在課堂上開發的代碼 - 取10個數字,取其平均值。

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 

該代碼運行良好。我需要將它調整到一個等級計算器中(把它放在十個數字等級中,對它們進行平均,然後將平均值與一些預先設定的值進行比較以分配一個數字等級)。除AL之外的所有基本內容都不會像100很多 - 如果我輸入,比如5 100和5 80,它告訴我總數是132,平均值是13.

好的,所以我嘗試了AH和EAX來代替AL, AL沒有足夠的空間。這是代碼。

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 

此代碼崩潰。它將採取數字,如果我說,100 5次和50 5次,它告訴我總和是-42041476,然後崩潰。

這可能是一些非常基本的東西,但我很茫然。我在這裏做錯了什麼?

+0

通常的事情......忘記'div esi'將使用edx作爲股息的前32位。儘管這不影響總結。 'add ebx,1'也是錯誤的,因爲每個整數都是4個字節,所以需要'添加ebx,4'。 – Jester

回答

0

您至少有一個錯誤和一些概念問題。

概念:EAX是32位寄存器的名稱;該寄存器的低16位稱爲AX。在AX中,低8位稱爲AL,高位AH。

概念:涉及內存讀/寫N位的N位指令。當你使用AL時,你會讀/寫8位,而當你使用EAX時,你會讀/寫32位。

....所以你的主要總和環有一個bug,它從內存每次讀取32位:

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

比方說你有個字節[1,2,3,4]在[EBX ]。第一個循環將向EAX添加1234H,後續循環未知,因爲您正在讀取的內存超出了數組的範圍。崩潰可能是由於這個或完全不同的東西。

如果您的數據字節你可以看到他們一個接一個:

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

而在你的平均PROC你有div esi,但你的div之前你必須EDX,因爲你將被歸零[EDX ,EAX] 64位數字到ESI。您需要在該指令之前添加xor dx,dx