0
section .bss
num: resb 3
  
section .text
global _start
_start:
 ; Read input
 mov eax, 3
 mov ebx, 0
 mov ecx, num
 mov edx, 3
 int 80h
   
  sub byte [num+2], 1
  cmp byte [num+2], 255
jne skip_borrow
   
   sub byte [num+1], 1
   cmp byte [num+1], 255
jne skip_borrow

   sub byte [num], 1

skip_borrow:
   cmp byte [num], 0
jne skip_carry
   mov byte [num+1], 9
   mov byte [num+2], 9  
skip_carry:      

 mov eax, 4
 mov ebx, 1
 mov ecx, num
 mov edx, 3
 int 80h

 mov eax, 1
 mov ebx, 0
 int 80h

The code is reading three digit input number and one digit input number. subtracting one digit number from lower than 100 and higher than 100 works. However, subtracting from 100, 200, 300 is giving wrong output. For example, 100 minus 1 gives me 10/ not 99 or 099 and 200 minus 1 gives me 20/ not 199. How do I solve this issue.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Ki Kim
  • 1
  • 1
  • You're working with *ASCII* digits, not binary integers, so you want to check for going below `'0'` (0x30), not `0` (0x0). – Peter Cordes Mar 26 '23 at 14:54
  • 2
    As you're working with multiple units, you have to implement carry for addition and borrow for subtraction across those multiple units. If the units are decimal ASCII digits then carry happens with > '9' and borrow when < '0'. To find the values of '0' and '9' look them up in an ASCII chart. Alternately, you can convert the ASCII digits to integers 0-9, then check arithmetic for for > 9 and/or < 0, to carry/borrow, and finally convert them back to ASCII digits if that's what you want. – Erik Eidt Mar 26 '23 at 15:04
  • 1
    Typical bigint systems will use integers (whether byte- or word- sized), rather than ASCII digits in storage because when you add/subtract/etc.. two such numbers together, it is easier to do the arithmetic with integers rather than ASCII digits — for example, we can multiply 5x6=30, but to multiply '5' x '6' gives very strange answers: '5' is 53 and '6' is 54; 53 x 54 = 2862, Conversion from string to integer forms then happens on input and output while internal storage uses an integer form more ready for arithmetic. – Erik Eidt Mar 26 '23 at 15:13
  • @ErikEidt: I added the [bigint] tag because this implementation choice (of working with separate digits) is effectively that. IDK if the OP is interested in extending it to work with numbers that wouldn't fit in a register as a 32-bit binary integer. But yeah, [NASM Assembly convert input to integer?](https://stackoverflow.com/q/19309749) / [How do I print an integer in Assembly Level Programming without printf from the c library? (itoa, integer to decimal ASCII string)](https://stackoverflow.com/a/46301894) would be the standard way for integers up to 2^32 - 1 – Peter Cordes Mar 26 '23 at 15:23

0 Answers0