0

I wrote a program in assembly to ask the user to enter two numbers one by one and print the result on the console after performing addition on the two numbers. after compiling the program in x86 architecture, when I run the program, the program asks two numbers. but the problem is that, if I enter two numbers one-by-one, and the result of the consecutive numbers are grater than 9, it produces unexpected result on the screen. below I mention the steps, I go through, and face problem.

  1. below is a simple program, written in assembly code:
; firstProgram.asm

section .data
msg1 db "please enter the first number: ", 0xA,0xD
len1 equ $- msg1
msg2 db "please enter the second number: ", 0xA,0xD
len2 equ $- msg2
msg3 db "the result is: "
len3 equ $- msg3

section .bss
num1 resb 2
num2 resb 2
result resb 2


section .code
global _start

_start:
; ask the user to enter the first number 
mov eax, 4
mov ebx, 1
mov ecx, msg1
mov edx, len1
int 0x80

; store the number in num1 variable 
mov eax, 3
mov ebx, 0
mov ecx, num1
mov edx, 2
int 0x80

; print the first number
mov eax, 4
mov ebx, 1
mov ecx, num1
mov edx, 2
int 0x80


; ask the user to enter the second number 
mov eax, 4
mov ebx, 1
mov ecx, msg2
mov edx, len2
int 0x80

; store the number, enter by the user in num2 variable 
mov eax, 3
mov ebx, 0
mov ecx, num2
mov edx, 2
int 0x80

; print the second number, enter by user 
mov eax, 4
mov ebx, 1
mov ecx, num2
mov edx, 2
int 0x80

; move the two numbers to eax and ebx register 
; and subtract zero to convert it into decimal
mov eax, [num1]
sub eax, '0'

mov ebx, [num2]
sub ebx, '0'

;add two numbers 
; and add zero to convert back into ascii 
add eax, ebx
add eax, '0'

; store the number in result variable 
mov [result], eax

; print a message to the user before printing the result
mov eax, 4
mov ebx, 1
mov ecx, msg3
mov edx, len3
int 0x80

; now print the result 
mov eax, 4
mov ebx, 1
mov ecx, result
mov edx, 2
int 0x80

; exit the program
mov eax, 1
mov ebx, 0
int 0x80
  1. after written the code, I compiled and execute it on the terminal as follows:
nasm -f firstProgram.asm -o firstProgram.o
ld -m elf_i386 -s -o first firstProgram.o
./first
<blockquote>
please enter the first number: 

5
please enter the second number: 

3
the result is: 8please enter the first number: 

6
please enter the second number: 

4
the result is: :please enter the first number: 

4
please enter the second number: 

67the result is: :Aplease enter the first number: 

25please enter the second number: 

 the result is: 5
</blockquote>

can anyone explain the reason with example?

Nate Eldredge
  • 48,811
  • 6
  • 54
  • 82
  • 2
    `num1 resb 2` so 2 bytes are reserved for `num1`, then `mov eax, [num1]` which loads 4 bytes from there? Also, your scheme of subtracting 0 is only correct for 1-digit numbers. If you think for a little bit, you'll see that for multi-digit numbers you need something with actual division. – Nate Eldredge Jun 15 '21 at 05:58
  • 1
    For other [tag:assembly] stalkers: is there a canonical question somewhere about operand size mismatches? I'm wondering if there is somewhere to point people with this kind of bug, instead of re-explaining it again and again. If not, maybe we should make one. – Nate Eldredge Jun 15 '21 at 06:00
  • @NateEldredge: I don't know of a good one. But yeah it comes up a lot, in two main form: dword store to `resb 1` or 2 overwriting other stuff, or dword load instead of `movzx eax, byte [mem]`, and then `cmp eax, '0'` but the upper bytes have non-0 garbage. I've gone digging for duplicates multiple times, but I don't remember whether I've eventually found a viable duplicate or not. I think not a clean one, at best a Q&A where it was one of multiple problems, so it's just one of multiple things an answer mentions. – Peter Cordes Jun 15 '21 at 10:13
  • For the byte-load version of the problem, there's [Why can't I move directly a byte to a 64 bit register?](https://stackoverflow.com/q/22621340). Or [How to load a single byte from address in assembly](https://stackoverflow.com/q/20727379) with an answer that unfortunately starts off suggesting loading into AL, not zero-extending. But neither of those explain that `resb 2` isn't 4 bytes, and don't cover the store problem. – Peter Cordes Jun 15 '21 at 10:15
  • @Eldredge oh my dear, this assembly language is making me very tension. assume that I've no programming experience any more. please make me understand it. the reason, why i am worried about it is, I am trying to understand the computer more deeply. assembly teaches us something new, that I have not learnt in other languages, such as java, c/c++ and python. currently, I have much confusion about registers, al, ah, ax, eax, rax. I understand it, but you know, I'm new in assembly. so I need a good answer. I hope you must help me – chandan dora Jun 16 '21 at 11:25

1 Answers1

-2

What about if you clean the registers after you print the output?

You can do an xor of the registers, that will clean all the garbage that you stored from last sum, ie:

; Clean registers.
xor eax, eax 
xor ebx, ebx
xor edx, edx
xor ecx, ecx
  • I don't see how that can possibly help. It looks to me like all relevant registers are overwritten after the output anyway. – Nate Eldredge Jun 15 '21 at 06:01