Calculator in Assembly Language - Linux x86 & NASM - Division?

You're reading two bytes (characters) into num1 and num2 for your number input. This will generally be a single digit (0-9) that you are typing in and a newline character. When you go to do an operation, you read 2 bytes each into ax and bx, so if num1 was 5 and num2 was 1, ax will be 0xa35 and bx will be 0xa31.

You then subtract 0x30 from each and divide, giving 1 in all cases, which you then convert to 0x31 '1' and print.

Up vote 0 down vote favorite share g+ share fb share tw.

I am making a calculator in assembly language to be executed on an x86 processor. Basically, my calculator asks the user to enter two numbers and then to indicate which operation (addition, subtraction, multiplication and division) want to do with them. My calculator adds, subtracts and multiplies correctly but is unable to divide.

In making a division, I always get 1 as the result. Then I leave my application code complete: section . Data ; Messages msg1 db 10,'-Calculator-',10,0 lmsg1 equ $ - msg1 msg2 db 10,'Number 1: ',0 lmsg2 equ $ - msg2 msg3 db 'Number 2: ',0 lmsg3 equ $ - msg3 msg4 db 10,'1.

Add',10,0 lmsg4 equ $ - msg4 msg5 db '2. Subtract',10,0 lmsg5 equ $ - msg5 msg6 db '3. Multiply',10,0 lmsg6 equ $ - msg6 msg7 db '4.

Divide',10,0 lmsg7 equ $ - msg7 msg8 db 'Operation: ',0 lmsg8 equ $ - msg8 msg9 db 10,'Result: ',0 lmsg9 equ $ - msg9 msg10 db 10,'Invalid Option',10,0 lmsg10 equ $ - msg10 nlinea db 10,10,0 lnlinea equ $ - nlinea section . Bss ; Spaces reserved for storing the values? Provided by the user.

Opc resb 2 num1 resb 2 num2 resb 2 result resb 2 section . Text global _start _start: ; Print on screen the message 1 mov eax, 4 mov ebx, 1 mov ecx, msg1 mov edx, lmsg1 int 80h ; Print on screen the message 2 mov eax, 4 mov ebx, 1 mov ecx, msg2 mov edx, lmsg2 int 80h ; We get num1 value. Mov eax, 3 mov ebx, 0 mov ecx, num1 mov edx, 2 int 80h ; Print on screen the message 3 mov eax, 4 mov ebx, 1 mov ecx, msg3 mov edx, lmsg3 int 80h ; We get num2 value.

Mov eax, 3 mov ebx, 0 mov ecx, num2 mov edx, 2 int 80h ; Print on screen the message 4 mov eax, 4 mov ebx, 1 mov ecx, msg4 mov edx, lmsg4 int 80h ; Print on screen the message 5 mov eax, 4 mov ebx, 1 mov ecx, msg5 mov edx, lmsg5 int 80h ; Print on screen the message 6 mov eax, 4 mov ebx, 1 mov ecx, msg6 mov edx, lmsg6 int 80h ; Print on screen the message 7 mov eax, 4 mov ebx, 1 mov ecx, msg7 mov edx, lmsg7 int 80h ; Print on screen the message 8 mov eax, 4 mov ebx, 1 mov ecx, msg8 mov edx, lmsg8 int 80h ; We get the option selected. Mov ebx,0 mov ecx,opc mov edx,2 mov eax,3 int 80h mov ah, opc ; Move the selected option to the registry ah sub ah, '0' ; Convert from ascii to decimal ; We compare the value entered by the user to know what operation to perform. Cmp ah, 1 je add cmp ah, 2 je subtract cmp ah, 3 je multiply cmp ah, 4 je divide ; If the value entered by the user does not meet any of the above ; conditions then we show an error message and we close the program.

Mov eax, 4 mov ebx, 1 mov ecx, msg10 mov edx, lmsg10 int 80h jmp exit add: ; We keep the numbers in the registers eax and ebx mov eax, num1 mov ebx, num2 ; Convert from ascii to decimal sub eax, '0' sub ebx, '0' ; Add add eax, ebx ; Conversion from decimal to ascii add eax, '0' ; We move the result mov result, eax ; Print on screen the message 9 mov eax, 4 mov ebx, 1 mov ecx, msg9 mov edx, lmsg9 int 80h ; Print on screen the result mov eax, 4 mov ebx, 1 mov ecx, result mov edx, 1 int 80h ; We end the program jmp exit subtract: ; We keep the numbers in the registers eax and ebx mov eax, num1 mov ebx, num2 ; Convert from ascii to decimal sub eax, '0' sub ebx, '0' ; Subtract sub eax, ebx ; Conversion from decimal to ascii add eax, '0' ; We move the result mov result, eax ; Print on screen the message 9 mov eax, 4 mov ebx, 1 mov ecx, msg9 mov edx, lmsg9 int 80h ; Print on screen the result mov eax, 4 mov ebx, 1 mov ecx, result mov edx, 1 int 80h ; We end the program jmp exit multiply: ; We store the numbers in registers ax and bx mov ax, num1 mov bx, num2 ; Convert from ascii to decimal sub ax, '0' sub bx, '0' ; Multiply. AL = AX x BX mul bx ; Conversion from decimal to ascii add al, '0' ; We move the result mov result, al ; Print on screen the message 9 mov eax, 4 mov ebx, 1 mov ecx, msg9 mov edx, lmsg9 int 80h ; Print on screen the result mov eax, 4 mov ebx, 1 mov ecx, result mov edx, 1 int 80h ; We end the program jmp exit divide: ; IN THIS LABEL IS THE ERROR! ; We store the numbers in registers ax and bx mov dx, 0 mov ax, num1 mov bx, num2 ; Convert from ascii to decimall sub ax, '0' sub bx, '0' ; Division.

AX = DX:AX / BX div bx ; Conversion from decimal to ascii add ax, '0' ; We move the result mov result, ax ; Print on screen the message 9 mov eax, 4 mov ebx, 1 mov ecx, msg9 mov edx, lmsg9 int 80h ; Print on screen the result ; ALWAYS PRINTS 1 mov eax, 4 mov ebx, 1 mov ecx, result mov edx, 1 int 80h ; We end the program jmp exit exit: ; Print on screen two new lines mov eax, 4 mov ebx, 1 mov ecx, nlinea mov edx, lnlinea int 80h ; End the program mov eax, 1 mov ebx, 0 int 80h The error must be found inside the tag "divide". Why do I always get 1 as result of a division? I hope that someone with more experience can help me with this.

Linux assembly x86 nasm division link|improve this question edited Feb 25 at 13:23Bo Persson23.2k51545 asked Feb 24 at 17:59Nicolas Obesio1.

1 Even though you're coding in assembly language, you should use the C library to make system calls, and you should have your program entry point be main, not _start. – Zack Feb 24 at 18:51.

You're reading two bytes (characters) into num1 and num2 for your number input. This will generally be a single digit (0-9) that you are typing in and a newline character. When you go to do an operation, you read 2 bytes each into ax and bx, so if num1 was 5 and num2 was 1, ax will be 0xa35 and bx will be 0xa31.

You then subtract 0x30 from each and divide, giving 1 in all cases, which you then convert to 0x31 '1' and print. Now in other cases (add/sub), you're actually loading 4 bytes into eax and ebx. So when you add 5 and 1, you'll get 0xa310a35 in eax and 0x?0a31 in ebx (the?

Comes from whatever happened to be in result. ) However, after subtracting 0x30 from each and adding, the lowest byte of eax will 0x06, so you'll print 6 as you ignore what is in the upper bytes.

Thank you very much for responding, but I can not fully understand your answer. Could you please write your answer in the form of code? Sorry for the inconvenience.

– Nicolas Obesio Feb 24 at 18:58 I also try doing this but I get "Floating Comma Exception": ` mov ax, num1 mov bl, num2 ; Convert from ascii to decimall sub ax, '0' sub bl, '0' ; Division. AL = DX:AX / BX div bl ; Conversion from decimal to ascii add al, '0' ; We move the result mov result, al` – Nicolas Obesio Feb 24 at 19:07 @NicolasObesio: If you only accept single digits as input, you should read only a single byte. Use mov al,num and mov result,al etc. and do all relevant operations only on single bytes.

– drhirsch Feb 25 at 13:41 @ChrisDodd: I think you nailed it. – drhirsch Feb 25 at 13:42.

Thank you all very much. My calculator finally works. Here is my final code: section .

Data ; Messages msg1 db 10,'-Calculator-',10,0 lmsg1 equ $ - msg1 msg2 db 10,'Number 1: ',0 lmsg2 equ $ - msg2 msg3 db 'Number 2: ',0 lmsg3 equ $ - msg3 msg4 db 10,'1. Add',10,0 lmsg4 equ $ - msg4 msg5 db '2. Subtract',10,0 lmsg5 equ $ - msg5 msg6 db '3.

Multiply',10,0 lmsg6 equ $ - msg6 msg7 db '4. Divide',10,0 lmsg7 equ $ - msg7 msg8 db 'Operation: ',0 lmsg8 equ $ - msg8 msg9 db 10,'Result: ',0 lmsg9 equ $ - msg9 msg10 db 10,'Invalid Option',10,0 lmsg10 equ $ - msg10 nlinea db 10,10,0 lnlinea equ $ - nlinea section . Bss ; Spaces reserved for storing the values?

Provided by the user. Opc: resb 2 num1: resb 2 num2: resb 2 result: resb 2 section . Text global _start _start: ; Print on screen the message 1 mov eax, 4 mov ebx, 1 mov ecx, msg1 mov edx, lmsg1 int 80h ; Print on screen the message 2 mov eax, 4 mov ebx, 1 mov ecx, msg2 mov edx, lmsg2 int 80h ; We get num1 value.

Mov eax, 3 mov ebx, 0 mov ecx, num1 mov edx, 2 int 80h ; Print on screen the message 3 mov eax, 4 mov ebx, 1 mov ecx, msg3 mov edx, lmsg3 int 80h ; We get num2 value. Mov eax, 3 mov ebx, 0 mov ecx, num2 mov edx, 2 int 80h ; Print on screen the message 4 mov eax, 4 mov ebx, 1 mov ecx, msg4 mov edx, lmsg4 int 80h ; Print on screen the message 5 mov eax, 4 mov ebx, 1 mov ecx, msg5 mov edx, lmsg5 int 80h ; Print on screen the message 6 mov eax, 4 mov ebx, 1 mov ecx, msg6 mov edx, lmsg6 int 80h ; Print on screen the message 7 mov eax, 4 mov ebx, 1 mov ecx, msg7 mov edx, lmsg7 int 80h ; Print on screen the message 8 mov eax, 4 mov ebx, 1 mov ecx, msg8 mov edx, lmsg8 int 80h ; We get the option selected. Mov ebx,0 mov ecx,opc mov edx,2 mov eax,3 int 80h mov ah, opc ; Move the selected option to the registry ah sub ah, '0' ; Convert from ascii to decimal ; We compare the value entered by the user to know what operation to perform.

Cmp ah, 1 je add cmp ah, 2 je subtract cmp ah, 3 je multiply cmp ah, 4 je divide ; If the value entered by the user does not meet any of the above ; conditions then we show an error message and we close the program. Mov eax, 4 mov ebx, 1 mov ecx, msg10 mov edx, lmsg10 int 80h jmp exit add: ; We keep the numbers in the registers al and bl mov al, num1 mov bl, num2 ; Convert from ascii to decimal sub al, '0' sub bl, '0' ; Add add al, bl ; Conversion from decimal to ascii add al, '0' ; We move the result mov result, al ; Print on screen the message 9 mov eax, 4 mov ebx, 1 mov ecx, msg9 mov edx, lmsg9 int 80h ; Print on screen the result mov eax, 4 mov ebx, 1 mov ecx, result mov edx, 2 int 80h ; We end the program jmp exit subtract: ; We keep the numbers in the registers al and bl mov al, num1 mov bl, num2 ; Convert from ascii to decimal sub al, '0' sub bl, '0' ; Subtract sub al, bl ; Conversion from decimal to ascii add al, '0' ; We move the result mov result, al ; Print on screen the message 9 mov eax, 4 mov ebx, 1 mov ecx, msg9 mov edx, lmsg9 int 80h ; Print on screen the result mov eax, 4 mov ebx, 1 mov ecx, result mov edx, 1 int 80h ; We end the program jmp exit multiply: ; We store the numbers in registers al and bl mov al, num1 mov bl, num2 ; Convert from ascii to decimal sub al, '0' sub bl, '0' ; Multiply. AX = AL x BL mul bl ; Conversion from decimal to ascii add ax, '0' ; We move the result mov result, ax ; Print on screen the message 9 mov eax, 4 mov ebx, 1 mov ecx, msg9 mov edx, lmsg9 int 80h ; Print on screen the result mov eax, 4 mov ebx, 1 mov ecx, result mov edx, 1 int 80h ; We end the program jmp exit divide: ; We store the numbers in registers ax and bx mov al, num1 mov bl, num2 mov dx, 0 mov ah, 0 ; Convert from ascii to decimall sub al, '0' sub bl, '0' ; Division.

AL = AX / BX div bl ; Conversion from decimal to ascii add ax, '0' ; We move the result mov result, ax ; Print on screen the message 9 mov eax, 4 mov ebx, 1 mov ecx, msg9 mov edx, lmsg9 int 80h ; Print on screen the result mov eax, 4 mov ebx, 1 mov ecx, result mov edx, 1 int 80h ; We end the program jmp exit exit: ; Print on screen two new lines mov eax, 4 mov ebx, 1 mov ecx, nlinea mov edx, lnlinea int 80h ; End the program mov eax, 1 mov ebx, 0 int 80h.

I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.

Related Questions