多次读取后错误的结果

时间:2017-08-14 00:24:38

标签: linux assembly x86 nasm

我想知道有人可以帮助我使用我的代码,我想从x86中的stdin读取多次,但是当我第二次阅读时,它忽略了数字而只是添加了50.我想要它工作,以便我可以多次调用它,因为我需要通过任意数字添加寄存器EAX(我将在稍后从变量A,B等加载)

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

1 个答案:

答案 0 :(得分:2)

在atoi,第五条指令

    je .end_atoi

测试此功能中尚未设置的Z标志。所以它是根据在调用atoi之前发生的任何事情的Z值跳转的,这是leer中的读取系统调用。

要么

    test bl, bl
在该je指令之前

或者只是移除je,因为字符串的结尾将被随后的cmp'0'捕获。

但这不是一个完整的修复:read系统调用不会null终止输入。 Leer应该使用读取的字节数(由读取系统调用返回)在输入后在缓冲区中放置一个空字节。