汇编语言崩溃时的等级平均值

时间:2015-11-30 17:08:34

标签: assembly x86 irvine32

我正在尝试调整我们在课堂上开发的一些代码并遇到问题。

这是我们在课堂上开发的代码 - 取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然后崩溃。

它可能是非常基本的东西,但我不知所措。我在这做错了什么?

1 个答案:

答案 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