Author Topic: Adding two numbers taken from key board  (Read 21223 times)

Offline joyrock

  • New Member
  • Posts: 1
Adding two numbers taken from key board
« on: March 04, 2010, 09:04:54 PM »
I want to take two numbers from keyboard and after adding show them in the screen.I am usung linux platform, and try to use int 80h call but can not figure out anything till now..pls help 

Offline Bryant Keller

  • Forum Moderator
  • Full Member
  • *****
  • Posts: 360
  • Country: us
    • About Bryant Keller
Re: Adding two numbers taken from key board
« Reply #1 on: March 05, 2010, 05:56:43 AM »
Use the SYS_read system call to grab user input. That input will need to be validated to make sure the user entered a number. Then convert the input from a string to an integer. Repeat the process for the second number. Next you'll want to use the ADD instruction to preform the integer addition on the converted inputs. And finally you'll need to convert the result to a string and use SYS_write to display the string on the screen.

Code: (SYS_read) [Select]
EDX = Length of Buffer
ECX = Address of Buffer
EBX = 0
EAX = 3

Code: (SYS_write) [Select]
EDX = Length of String
ECX = Address of String
EBX = 1
EAX = 4

I hope this helps. Maybe if you wrote some code we could help you a little better.  :-\

Regards,
Bryant Keller

About Bryant Keller
bkeller@about.me

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Adding two numbers taken from key board
« Reply #2 on: March 05, 2010, 10:18:20 AM »
We don't really get "numbers" from the keyboard, we get characters. Well, we do get numbers - the ascii codes for the characters... the ascii code for the character '1' is not 1. This is why we have to "convert" from string to number... and back, when we want to display a number. Typing "man ascii" should get you an ascii chart. As you can see, the ascii code for '1' is (skip the pesky octal) 49 decimal or 0x31 hex. Fortunately, the codes for '0' through '9' are contiguous (This is not so in  all systems of encoding characters, I'm told! These systems have mostly been abandoned. Wonder why?). You don't really need to remember the numbers, "sub al, '0'" will convert from character to number, and "add dl, '0'" from number to character, and the '0' makes the code somewhat "self-documenting" compared to "sub al, 060q" or so...

Simple enough for a single digit. Multi-digit numbers have to be handled one at a time. Converting string->number, the general idea is: make sure we've got a(nother) valid decimal (or other) digit, multiply the "result so far" (which should begin with zero, obviously) by ten, add in the new digit - as a number, not a character - and go back for more. A string entered from the keyboard will end with a linefeed (ascii 10). When you find that, you're done. Up to you what you want to do if you encounter invalid characters before that. Easiest thing - what C does - is to treat any invalid character as the end of the string, and whatever you've got so far is the number. But you could holler "A NUMBER, Idiot!" or "'!@#$' is not a number I can understand. Please try again.", or whatever... You may also want to think about overflow. Easiest thing is to just let it "roll over" and use the result, modulo 32 bits. This is "correct", but possibly not what the user expects. You may want to detect it and complain "5000000000 won't fit into 32 bits. Please try again." (or "Not so big, Idiot!") Limiting the number of characters the user can enter is a possible way around this, too.

Converting number->string, so we can print it, is probably going to involve the "div" instruction. There are other - faster - ways to do it, but "div" is easy. It does have a "gotcha" that often bites newbies...

Code: [Select]
mov ebx, 10
div ebx

That will divide edx:eax (that is, edx * 4G + eax) by ten, leaving the quotient in eax and the remainder in edx. If the result won't fit in eax, it causes an exception. Since the number we're dividing will presumably fit in eax, we forget about edx, but the CPU does not forget! We want edx to be zero, and since the "div" instruction itself alters edx, we're going to have to zero it before the "div", every time!

After the "div", the remainder in edx is the digit we're looking for. We get 'em in the "wrong" order, though. We can stuff 'em in the buffer starting at the end, and working forward, or we could "push" 'em on the stack in the order we get 'em, and "pop" 'em off in the right order to print. A recursive implementation is cute. Don't forget to add '0' somewhere along the line, to convert the digit to a character!

In between, you'll need the "add" instruction. I don't think you'll have any trouble figuring that out. Remember "add eax, [first_number]", not "add eax, first_number"! This is another place where you might encounter an overflow of 32 bits, if you want to do something about it.

Don't forget to exit cleanly!

Just a thought... if you "can not figure out anything till now", you might want to tackle this in smaller steps...

Best,
Frank