0

I want to write a simple assembly program to receive user input 'iterations', then it prints the numbers from zero till 'iterations'. example, of the expected output:

enter the number of iterations
4
performing the loop: 
0123
exiting.

But the actual output is an infinite loop with dummy characters ! here is my code, I have commented every operation:

section .data
    user_ask: db "enter the number of iterations", 0xA
    str_len: equ $ - user_ask
    out_msg: db "performing the loop: ", 0xA
    out_len: equ $ - out_msg 
    exiting: db  0xA, "exiting.", 0xA
    ext_len: equ $ - exiting
global _start

section .bss
    out_buff resb 4
    iterations resb 2

section .text
_start:
;; Prompt the user to enter a number 
    mov eax, 4
    mov ebx, 1
    mov ecx, user_ask
    mov edx, str_len
    int 0x80
;; Read user input and stores that ot 'iterations'
    mov eax, 3
    mov ebx, 2
    mov ecx, iterations
    mov edx, 5
    int 0x80

;; Message: "performing the loop: ... "
    mov eax, 4
    mov ebx, 1
    mov ecx, out_msg
    mov edx, out_len
    int 0x80
;; Setting edi to zero
    xor edi, edi
.loop:
    mov ecx, edi
    add ecx, 0x30
    mov [out_buff], ecx
    mov ecx, out_buff
;; Writing the numbers
    mov eax, 4
    mov ebx, 1
    mov edx, 1
    int 0x80
    inc edi
;; Compare current edi with user input 'iterations'
    cmp edi, DWORD[iterations]
    jl .loop

.exit:
; Message: "exiting." 
    mov eax, 4
    mov ebx, 1
    mov ecx, exiting
    mov edx, ext_len
    int 0x80
;exit
    mov eax, 1
    mov ebx, 0
    int 0x80

the problem is happening in the compare line, I think I am comparing an ASCII value with an integer or so...

BTW: I am running this on ubuntu 20.04 with nasm, as follow: nasm -f elf64 loop.asm && ld -o loop loop.o && ./loop

  • Ok but what exactly is the problem here? What is the result and how does it differ from expected one? Please be more specific. – PookyFan Aug 21 '22 at 19:38
  • I edited my question ,the problem is that when I ask the user to enter a number, it will be stored in the ASCII form, the register edi is used as counter, I am incrementing its value each iteration, I used 'out_buff" to store the value of edi and compare it with 'iterations', but this is not working – Lalmi Ahmed Aug 21 '22 at 20:43
  • `resb 2` is wrong for memory you're accessing as a 4-byte dword. But probably the top 2 bytes happen to be zero. Still, single-step it with a debugger and look at register values. Also, if you're going to use 32-bit `int 0x80` system calls, you should be building your program as 32-bit (`nasm -felf32` and `ld -melf_i386` or `gcc -m32 -nostdlib`). [What happens if you use the 32-bit int 0x80 Linux ABI in 64-bit code?](https://stackoverflow.com/a/46087731) – Peter Cordes Aug 21 '22 at 21:06
  • The loop isn't infinite, e.g. entering `1`, I get the expected 2672 bytes of output, which your prompt length plus `0x0a31` = 2609 (the number represented by using `db "1", 0xa, 0, 0` at a 4-byte little-endian number, i.e. the ASCII bytes of your input string including newline as a number.) I checked with `./foo | wc` and typing `1`. Apparently `echo 1 | ./foo | wc` doesn't work, so you have some other bug as well. Oh, `strace` shows you're reading from fd 2 (stderr), not fd 0 (stdin). Both are normally connected to the terminal, but piping input only redirects fd 0. – Peter Cordes Aug 21 '22 at 21:10

0 Answers0