Author Topic: (SOLVED)noobie-simple keyboard input program I can't get to work - linux(SOLVED)  (Read 14259 times)

Offline mwayman

  • Jr. Member
  • *
  • Posts: 2
Hi guys,
I am new to assembly and I have been trying to write a program using very simple code that does the following:
Prompts the user to enter a 2 digit number -- **user enters a 2 digit number** -- prompts the user to enter another 2 digit number -- **user enters another 2 digit number** -- the program then prints the results with the format "%d plus %d equals %d"

THE PROBLEM -- The first number reads in fine and is converted to decimal fine, but the second number does not read in correctly. it is the same code for reading both numbers i just can't figure out how to fix it.
please help the noobie.
and thank you

I would like to read the numbers in one byte at a time but just as a side note if someone can tell me how to use atoi correctly would help me out a great deal.

Code: [Select]
extern printf

        section .data
;; create the prompt and output format
prompt: db "Enter a number", 10, 0
fmt:    db "%d plus %d equals %d", 10, 0

       section .bss
        ;; create the variable that will hold the data
digit1: resb 2
digit2: resb 2
digit3: resb 2
digit4: resb 2
num0:   resb 4
num1:   resb 4


        ;; body of the program
        section .text
        global main
main:
        push ebp
        mov ebp, esp

        push prompt             ; push prompt to stack
        call printf

        mov eax, 3              ; read in the first digit, first number
        mov ebx, 0
        mov ecx, digit1
        mov edx, 1
        int 80h
        mov eax, 3              ; read in second digit, first number
        mov ebx, 0
        mov ecx, digit2
        mov edx, 2
        int 80h

        sub byte[digit1], 30h   ; convert first digit to decimal value
        sub byte[digit2], 30h   ; convert second digit to decimal value
        mov al, byte[digit1]    ; move digit1 for multiplication
        mov bl, 10              ; move 10 to bl for multiplication
        mov bl, 10              ; move 10 to bl for multiplication
        mul bl                  ; multiply digit1 by 10 and save in al
        movzx bx, byte[digit2]  ; extended move digit 2 to bx
        add ax, bx              ; add the first digit*10 and second digit
        mov byte[num0], al      ; put results in num0

        push prompt             ; display prompt
        call printf

        mov eax, 3              ; read in the first digit, second number
        mov eax, 0
        mov ecx, digit3
        mov edx, 1
        int 80h
        mov eax, 3              ;read in the 2nd digit, second number
        mov ebx, 0
        mov ecx, digit4
        mov edx, 2

        sub byte[digit3], 30h   ;convert digit3 to decimal value
        sub byte[digit4], 30h   ;convert digit4 to decimal value
        mov al, byte[digit3]    ; move digit3 for multiplication
        mov bl, 10              ; move 10 to bl for multiplication
        mul bl                  ; multiply digit 3 by 10
        movzx bx, byte[digit4]  ; extended move
        add ax, bx              ; combine digit 3 and 4
        mov byte[num1], al      ; save results in num1


        mov eax, 0
        add eax, [num0]
        add eax, [num1]         ; add number 1 and 2 to eax
        push eax                ; save result to stack
        mov eax, [num1]         ; move result 2 to eax
        push eax                ; save to stack
        mov eax, [num0]         ; move result 1 to eax
        push eax                ; save result 1 to stack


        push fmt                ; push the format to stack
        call printf             ; display the format with results

        add esp, 24             ; return to where we were
        mov esp, ebp
        pop ebp
        mov eax, 1              ; exit program
        mov ebx, 0
        ret
« Last Edit: June 01, 2013, 02:42:31 PM by mwayman »

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: noobie - simple program I can't get to work - linux
« Reply #1 on: June 01, 2013, 02:31:16 AM »
First issue:
Code: [Select]
        mov eax, 3              ;read in the 2nd digit, second number
        mov ebx, 0
        mov ecx, digit4
        mov edx, 2
; uhhm... int 80h ?
There's more wrong with it than this. It is now reading two numbers, but is... confused... about the second number. I strongly suspect that this is an issue with loading bytes and pushing dwords. You use "movzx" to advantage - pity we don't have an "addzx". :) I'll look some more, but wanted to let you know my preliminary results...

Best,
Frank


Edit: some discussion here:
http://forum.nasm.us/index.php?topic=1514.0
that might interest you. We get pretty far afield, but I think there's an example of "atoi" in it...
« Last Edit: June 01, 2013, 03:19:54 AM by Frank Kotler »

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: noobie - simple program I can't get to work - linux
« Reply #2 on: June 01, 2013, 04:56:49 AM »
Well, another typo in the getting of the second number. I probably altered this more than was strictly necessary, but I think it works now...

That's with an obedient user. If the pesky user enters one digit or three or a non-digit... you're borked.

Best,
Frank

Code: [Select]
extern printf

        section .data
;; create the prompt and output format
prompt: db "Enter a number", 10, 0
fmt:    db "%d plus %d equals %d", 10, 0

       section .bss
        ;; create the variable that will hold the data
digit1: resb 2
digit2: resb 2
digit3: resb 2
digit4: resb 2
num0:   resb 4
num1:   resb 4


        ;; body of the program
        section .text
        global main
main:
        push ebp
        mov ebp, esp

        push prompt             ; push prompt to stack
        call printf

        mov eax, 3              ; read in the first digit, first number
        mov ebx, 0
        mov ecx, digit1
        mov edx, 1
        int 80h
        mov eax, 3              ; read in second digit, first number
        mov ebx, 0
        mov ecx, digit2
        mov edx, 2
        int 80h

        sub byte[digit1], 30h   ; convert first digit to decimal value
        sub byte[digit2], 30h   ; convert second digit to decimal value
        mov al, byte[digit1]    ; move digit1 for multiplication
        mov bl, 10              ; move 10 to bl for multiplication
;        mov bl, 10              ; move 10 to bl for multiplication
        mul bl                  ; multiply digit1 by 10 and save in al(ax!)
        movzx bx, byte[digit2]  ; extended move digit 2 to bx
        add ax, bx              ; add the first digit*10 and second digit
        mov byte[num0], al      ; put results in num0

        push prompt             ; display prompt
        call printf

        mov eax, 3              ; read in the first digit, second number
;        mov eax, 0 ; whoa! where did that come from??? Oh.
mov ebx, 0
        mov ecx, digit3
        mov edx, 1
        int 80h
        mov eax, 3              ;read in the 2nd digit, second number
        mov ebx, 0
        mov ecx, digit4
        mov edx, 2
int 80h ; !

        sub byte[digit3], 30h   ;convert digit3 to decimal value
        sub byte[digit4], 30h   ;convert digit4 to decimal value
        mov al, byte[digit3]    ; move digit3 for multiplication
        mov bl, 10              ; move 10 to bl for multiplication
        mul bl                  ; multiply digit 3 by 10
        movzx bx, byte[digit4]  ; extended move
        add ax, bx              ; combine digit 3 and 4
        mov byte[num1], al      ; save results in num1


        mov eax, 0
        add al, [num0]
        add al, [num1]         ; add number 1 and 2 to eax
        push eax                ; save result to stack

xor eax, eax  ; or mov eax, 0
        mov al, [num1]         ; move result 2 to eax
        push eax                ; save to stack

xor eax, eax
        mov al, [num0]         ; move result 1 to eax
        push eax                ; save result 1 to stack

        push fmt                ; push the format to stack
        call printf             ; display the format with results

        add esp, 24             ; return to where we were
        mov esp, ebp
        pop ebp
        mov eax, 1              ; exit program
        mov ebx, 0
        ret

Offline mwayman

  • Jr. Member
  • *
  • Posts: 2
Thank you sooo much Frank Kotler.
In my original code I had the int 80h
and no mov eax, 0 after the eax, 3

when I was copying it from putty it would only let me do a few lines at a time and things got jumbled up and I didn't clean it up from that as well as I had thought.

clearing eax and moving the num0 and num1 into al instead of eax like in the code you provided solved the issue.

I have a good grasp on higher level languages but started assembly a couple weeks ago to learn more about whats actually going on with the computer, its a good learning experience and there is so much to know.

Thanks for the fast response and the help