2 Replies - 3947 Views - Last Post: 13 October 2012 - 09:14 PM

#1 rileyh  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 4
  • Joined: 13-October 12

Linux nasm assembly program prints out random characters

Posted 13 October 2012 - 01:38 AM

I am writing a program to get an integer from the user, and then print out all the numbers from 0 up to the number. My code gets the input fine, but when printing it out, it prints continuously in what seems to be an endless loop. Here is my code:

SECTION .data           ; Constant variable declaration
len   EQU 32        ; Constant length
msg db "Enter a number: ", 0 ; Input message
msglen EQU $-msg             ; Input message length

SECTION .bss            ; Uninitialised data declaration
other resd len      ; Output counter that is incremented
data  resd len      ; Input data buffer 

SECTION .text           ; Main program initialiser

GLOBAL _start           ; Linker entry point declaration
_start:                 ; Entry point
nop                 ; This keeps the debugger happy :)/>

Msg:                    ; This section prints out the message
mov eax, 4          ; }
mov ebx, 1          ; }
mov ecx, msg        ; } System_write call
mov edx, msglen     ; }
int 80h             ; }

input:                  ; This section gets the integer from the user
mov eax, 3          ; }
mov ebx, 0          ; }
mov ecx, data       ; } System_read call
mov edx, len        ; }
int 80h             ; }

ASCIIAdj:   
mov ebp, 48         ; This line sets the counter to '0' ASCII

setup:                  ; This section adjusts the counter
mov [other], ebp    ; Increment counter 

loop:                   ; This section loops, printing out from zero to the number given
mov eax, 4          ; }
mov ebx, 1          ; }
mov ecx, other      ; } System_write call
mov edx, len        ; }
int 80h             ; }
mov eax, 1          ; Move 1 to eax
add ebp, eax        ; Add eax to ebp (essentially increment ebp)
    mov eax, other      ; move other to eax
    mov ebx, data       ; move data to ebx
    cmp eax, ebx        ; compare them
jne setup           ; If they are not the same, go back to the setup to increment other

exit:                   ; Exits the program
mov eax, 1          ; }
mov ebx, 0          ; } System_exit call
int 80h             ; }


Expected Output:
Enter a number: 6
0123456

General Semantics of the program:

Display "Enter a number: "
Read in an integer less than 32 bytes in size.
Set a counter variable to the ASCII value of zero
Loop:
Display the character, adding 1 to it, and checking to see if it is equal to the value    inputted.
If it is equal, goto the exit section and exit
Else loop.


Why does it loop continuously? I have incremented the counter, and compared the input and the counter, so why doesn't it break?

Thanks in advance

Is This A Good Question/Topic? 0
  • +

Replies To: Linux nasm assembly program prints out random characters

#2 GunnerInc  Icon User is offline

  • "Hurry up and wait"
  • member icon




Reputation: 858
  • View blog
  • Posts: 2,277
  • Joined: 28-March 11

Re: Linux nasm assembly program prints out random characters

Posted 13 October 2012 - 08:26 AM

Cross posted to:
http://www.daniweb.c...cters-generated

http://stackoverflow...nting-character

Others on SO have given you good answers, but I will add my 1/2 cents worth:
Loop is an x86 instruction, it should not be used as a label name. You will run into problems in doing this.

Learn to use a debugger, this is a must if you are going to use Assembly. Many problems you encounter can be easily fixed by stepping through your code in a debugger. "Why does my code loop forever?" When you run through a debugger, you will see your loop counter is not what you expect.

Please use descriptive label names! You are not restricted to a certain label name length, data and other are NOT good label names. I would name other - CurrentChar and data - CurrentCount or something similar, it makes your code self documenting and others will not be hesitant to debug your code.

Don't use hard coded numbers in system calls. You can create equates or defines which again, will make your code self documenting.
    mov     eax, sys_write      ; }
    mov     ebx, stdout         ; }
    mov     ecx, msg            ; } System_write call
    mov     edx, msglen         ; }
    int     80h                 ; }

Look at how easy that is to understand vs.
    mov eax, 4          ; }
    mov ebx, 1          ; }
    mov ecx, msg        ; } System_write call
    mov edx, msglen     ; }
    int 80h             ; }

Plus, it will cut down on typo bugs.

As noted, here are some changes to your code:
sys_exit    equ     1
sys_read    equ     3
sys_write   equ     4
stdin       equ     0
stdout      equ     1

SECTION .data           ; Constant variable declaration
len   EQU 32        ; Constant length
msg db "Enter a number: ", 0 ; Input message
msglen EQU $-msg             ; Input message length

SECTION .bss            ; Uninitialised data declaration
other resd len      ; Output counter that is incremented
data  resd len      ; Input data buffer 

SECTION .text           ; Main program initialiser

GLOBAL _start           ; Linker entry point declaration
_start:                 ; Entry point
nop                 ; This keeps the debugger happy :)/>

Msg:                    ; This section prints out the message
    mov     eax, sys_write      ; }
    mov     ebx, stdout         ; }
    mov     ecx, msg            ; } System_write call
    mov     edx, msglen         ; }
    int     80h                 ; }

input:                  ; This section gets the integer from the user
    mov     eax, sys_read       ; }
    mov     ebx, stdin          ; }
    mov     ecx, data           ; } System_read call
    mov     edx, len            ; }
    int     80h                 ; }

    mov     byte [other], 48    
    inc     byte [data]
 
PrintNum:                   ; This section loops, printing out from zero to the number given
    mov     eax, sys_write      ; }
    mov     ebx, stdout         ; }
    mov     ecx, other          ; } System_write call
    mov     edx, len            ; }
    int     80h                 ; }

    inc     byte [other]
    movzx   eax, byte[data]
    cmp     al, byte [other]
    jne     PrintNum            ; If they are not the same, go back to the setup to increment other

exit:                   ; Exits the program
    mov     eax, sys_exit       ; }
    mov     ebx, 0              ; } System_exit call
    int     80h                 ; }4


Note where we test for our loop condition, we use square brackets [] to use the value at address. If you don't use brackets, you are telling the cpu to use the address and not the value pointed to at address.
Was This Post Helpful? 0
  • +
  • -

#3 rileyh  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 4
  • Joined: 13-October 12

Re: Linux nasm assembly program prints out random characters

Posted 13 October 2012 - 09:14 PM

Thank you so much! It works great!
Sorry about the duplicate post here on DIC, it was an accident (I have never posted here before). I only came here because the answer I got on SO didn't work. I have used KDBG on Linux Mint, but I have almost no idea how to use it. I can step through code, but when I stepped through the code I posted, it kept crashing saying "program has received SIGINT, interrupt", or something, and later it received a segmentation fault. I don't know what they mean, so it isn't of much use to me.

Thanks again.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1