2

I'm creating an assembly language program with NASM on Linux. I'm trying to do a weighted average of 4 numbers where the 4th number entered has double the weighting of the others. If I use the numbers 30, 40, 50, 60, I'm calculating the weighted average as (30+40+50+60+60)/5. My code is:

SYS_EXIT  equ 1
SYS_READ  equ 3
SYS_WRITE equ 4
STDIN     equ 0
STDOUT    equ 1

segment .data 

   msg1 db "Enter exam grade 1: ", 0xA,0xD  
   len1 equ $- msg1 
   msg2 db "Enter exam grade 2: ", 0xA,0xD 
   len2 equ $- msg2 
   msg3 db "Enter exam grade 3: ", 0xA,0xD 
   len3 equ $- msg3 
   msg4 db "Enter final exam grade (worth double: ", 0xA,0xD 
   len4 equ $- msg4 
   msg5 db "The sum is: "
   len5 equ $- msg5

segment .bss

   num1 resb 3 
   num2 resb 3 
   num3 resb 3 
   num4 resb 3 
   res resb 4    

section .text
   global main    

main:            
   mov eax, SYS_WRITE         
   mov ebx, STDOUT         
   mov ecx, msg1         
   mov edx, len1 
   int 0x80                

   mov eax, SYS_READ 
   mov ebx, STDIN  
   mov ecx, num1 
   mov edx, 3
   int 0x80            

   mov eax, SYS_WRITE        
   mov ebx, STDOUT         
   mov ecx, msg2          
   mov edx, len2         
   int 0x80

   mov eax, SYS_READ  
   mov ebx, STDIN  
   mov ecx, num2 
   mov edx, 4
   int 0x80       

   mov eax, SYS_WRITE         
   mov ebx, STDOUT         
   mov ecx, msg3         
   mov edx, len3
   int 0x80                

   mov eax, SYS_READ 
   mov ebx, STDIN  
   mov ecx, num3 
   mov edx, 3
   int 0x80            

   mov eax, SYS_WRITE        
   mov ebx, STDOUT         
   mov ecx, msg4          
   mov edx, len4         
   int 0x80

   mov eax, SYS_READ  
   mov ebx, STDIN  
   mov ecx, num4 
   mov edx, 3
   int 0x80           

   mov eax, SYS_WRITE         
   mov ebx, STDOUT         
   mov ecx, msg5          
   mov edx, len5         
   int 0x80

   mov eax, [num1]      ; move num1 to register eax
   sub eax, '0'         ; sub '0' to convert eax bl from ASCII to decimal
   mov ebx, [num2]      ; move num2 to register ebx    
   sub ebx, '0'         ; sub '0' to convert ebx from ASCII to decimal
   mov ecx, [num3]      ; move num3 to register ecx
   sub ecx, '0'         ; sub '0' to convert ecx from ASCII to decimal
   mov edx, [num4]      ; move num4 to register edx
   sub edx, '0'         ; sub '0' to convert edx from ASCII to decimal
   add eax, ebx         ; add ebx to eax
   add eax, ecx         ; add ecx to eax
   add eax, edx         ; add edx to eax
   add eax, edx         ; add edx to eax again

   mov bl, '5'          ; sub '0' to convert bl from ASCII to decimal
   sub bl, '0'          ; make bl a decimal

   div bl               ; divide by bl
   add eax, '0'         ; add '0' to convert the sum from decimal to ASCII
   mov [res], eax       ; storing the sum in memory location res

   ; print the sum 
   mov eax, SYS_WRITE        
   mov ebx, STDOUT
   mov ecx, res         
   mov edx, 3        
   int 0x80

exit:    

   mov eax, SYS_EXIT   
   xor ebx, ebx 
   int 0x80

I can produce this exception if I enter these numbers:

Enter exam grade 1:
30
Enter exam grade 2:
40
Enter exam grade 3:
50
Enter final exam grade (worth double:
60
The sum is: Floating point exception

What causes my program to display Floating Point Exception (SIGFPE) and how can I fix this?

Michael Petch
  • 46,082
  • 8
  • 107
  • 198
  • What is the question? Where is the problem? I venture to guess that the floating point exception is on the division. – Michael Petch Nov 22 '15 at 05:28
  • I am reading in 4 numbers, and am adding them together (the last number counts twice) then I am trying to find the average by dividing by 5. I am getting a floating point exception from my div and I have no clue as to why. This is my first time programming in assembly language. – Jorge Mendoza Nov 22 '15 at 05:36
  • Thank you Michael for the help with the formatting, when I copied my code to stackoverflow it made it all wonky. – Jorge Mendoza Nov 22 '15 at 05:39
  • 1
    Has your instructor shown how to use the debugger (like gdb)? The reason you will get a floating point exception on that `div` (besides a Divide by zero) is if the value in `AX` divided by the value in `BL` is greater than 255. Likely you have a bogus value in `AX` – Michael Petch Nov 22 '15 at 05:43
  • I'm also curious if your instructor suggested using _printf_ and _scanf_ for this assignment? – Michael Petch Nov 22 '15 at 05:46
  • He has not. Could you link me to a debugger by chance? Yeah, that's what I have been reading across multiple sites but I do not know how to fix it. I believe that my problem stems from my additions. When I try printing the total of the numbers added, it does not give me the decimal value (it prints the ascii value, and it prints it incorrectly). – Jorge Mendoza Nov 22 '15 at 05:48
  • He did not specify on using printf. Scanf is not required, we are supposed to request user input (exam grades, 3 regular exams and 1 final worth double). – Jorge Mendoza Nov 22 '15 at 05:50
  • You have a lot going wrong in this code. One in particular is when you do this `mov eax, [num1]`. This moves 4 bytes into the 32 bit register _EAX_. You only subtract off '0' from the lower 8 bits, but there are characters in the upper bits of EAX too. I recommend you talk to your Teacher assistant or professor. I could provide a solution but I doubt you would understand it, which doesn't help anyone. Your code only allows for number between 0 and 9. You are basically doing all the string to integer conversions wrong. – Michael Petch Nov 22 '15 at 05:54
  • I asked about _scanf_ and _printf_ (and maybe even _atof_)because there was another student with a somewhat similar question today. That is here: http://stackoverflow.com/questions/33850789/using-atof-function-in-x86-nasm – Michael Petch Nov 22 '15 at 05:58
  • Thank you! I will update tomorrow on my findings. – Jorge Mendoza Nov 22 '15 at 06:08

0 Answers0