coolzoa
coolzoa

Reputation: 43

Wrong result after multiple read

I was wondering i someone could help me with my code, i want to read more than one time from the stdin in x86 but when i read the second time, it is ignoring the number and just add the 50. I want it to work so that i can call it as many times as i need to go adding the register EAX by an arbitrary number (which i will load from variables A,B,etc later on)

section .text
    global _start

_start:
  call leer
  call atoi
  add eax,10
  call itoa

  call imprimir
  call limpiar

  call leer
  call atoi
  add eax,50
  call itoa
  call imprimir

  jmp salir

;-----------ATOI
atoi:
    mov esi,Buffer ;move buffer address
    mov eax,0 ;where im going to keep result
    mov ebx,0 ;where i put char

.atoi_start:
    mov bl, byte[esi] ;get the char
    je .end_atoi
    cmp bl, '0' ;check if null
    jb .end_atoi
    cmp bl,'9'
    ja .end_atoi
    imul eax,10 ;multiplico resultado por 10
    sub bl,0x30 ;ascii->int
    add eax,ebx ;agegue el nuevo digito
    inc esi ;getting ready for next char
    jmp .atoi_start
.end_atoi:
    ret ;at this point i have int representation in eax


;-----------ITOA
itoa:
    mov ebx, eax ;mueve el numero en eax a ebx
    mov esi, Buffer
    mov ebx,10
    add esi,10
.itoa2:
    xor edx,edx
    div ebx 
    add dl,'0' ;lo convierte en char
    mov [esi],dl
    dec esi
    test eax,eax
    jnz .itoa2
    jz .doneItoa

.doneItoa:
    ret


;----------------------LIMPIAR
limpiar:
    ;limpia buffer usando eax
    xor eax,eax;
    xor edx,edx
    xor ecx,ecx

    mov ecx, 1100 ;tamano de veces que voy a limpiar
    lea edx, [Buffer] ;direccion inicial del buffer

.loop:
    mov [edx+ecx],eax ;voy a limpiar de atras para adelante
    dec ecx ;decremento contador y verifico si es 0 para seguir limiando
    jnz .loop
    ret

imprimir:
    mov eax,4
    mov ebx,1
    mov ecx,Buffer
    mov edx,1100 ;tamano
    int 0x80 ;syscall

;ahora imprimo nueva linea
    mov eax,4
    mov ebx,1
    mov ecx,nuevaLinea
    mov edx,1
    int 0x80
    ret

leer:
    ;vamos a poner el msg en pantalla
    mov eax,4 ;sys_write
    mov ebx,1 ;stdout
    mov ecx,msg ;paso el mensaje
    mov edx,lenMsg ;paso el largo del mensaje
    int 80h

    ;ahora leemos
    mov eax,3 ;sys_read
    mov ebx,2 ;stdin
    mov ecx,Buffer
    mov edx,1100
    int 80h
    ret

salir:
    mov rax,60 ;sys_exit
    mov rdi,0 ;codigo de salida
    syscall


section .data
   msg db 'Ingrese un numero: '
   lenMsg equ $-msg

   nuevaLinea db 10;nueva linea
   A dq 0


section .bss    
    Buffer: resb 1100

    B: resb 1100

Upvotes: 1

Views: 79

Answers (1)

prl
prl

Reputation: 12432

In atoi, the fifth instruction

    je .end_atoi

tests the Z flag which has not been set in this function. So it is jumping based on the value of Z from whatever happened before atoi is called, which is the read system call in leer.

Either put

    test bl, bl

before that je instruction or just remove the je, since the end of string will be caught by the cmp '0' that follows.

But that's not a complete fix: The read system call doesn't null terminate the input. Leer should use the number of bytes read (returned by the read system call) to place a null byte in the buffer after the input.

Upvotes: 2

Related Questions