我正在尝试调整我们在课堂上开发的一些代码并遇到问题。
这是我们在课堂上开发的代码 - 取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 :(得分:0)
您至少有一个错误和一些概念性问题。
概念:EAX是32位寄存器的名称;该寄存器的低16位称为AX。在AX中,低8位称为AL,高位称为AH。
概念:一个N位指令,涉及内存在内存中读取/写入N位。当你使用AL时,你会读/写8位,当你使用EAX时,你会读/写32位。
....所以你的主要求和循环有一个错误,它每次从内存中读取32位:
SumLoop:
add eax,[ebx]
add ebx,1
loop SumLoop
假设你在[EBX]有字节[1,2,3,4]。第一个循环将向EAX添加1234H,后续循环未知,因为您正在读取的内存超出了数组的范围。崩溃可能是由于这个或完全不同的东西。
如果您的数据是字节,您可以逐个阅读:
xor edx, edx
SumLoop:
mov dl,[ebx]
add eax, edx
inc ebx
loop SumLoop
在你的平均过程中你有div esi
但是在你div之前你的EDX必须归零,因为你将[EDX,EAX] 64位数除以ESI。您需要在该指令之前添加xor dx,dx