0

im trying to program in assembler and i need to do something in order to wait for user input key (only enter or space) witout enter, like y/n options. I read about 16h in dos, its a sys_Call similar in linux? i also read about disabling canonization but look too complicated to the curse level thanks

    section .bss
    buffer  resb 1
    input resb 1
section  .data

    lineasConsola dd 3  ; Lineas (sin informacion) mostradas por defecto
    lineasPantalla dd 3 
    lineasTotales dd 0
    lineasContador dd 0


section .text

    global _start

leerInput:

    push ebx
    push ecx
    mov eax, 3      ; sys_read
    mov ebx, 0
    mov ecx, input
    mov edx, 1
    int 80h
    pop ecx
    pop ebx
    ret

leerCaracter:

    mov eax,3       ; sys_read
    mov ecx,buffer  
    mov edx,1
    int 80h
    cmp eax,0       ;eof
    je final

imprimirCaracter:

    mov eax, 4          ; sys_write
    push ebx            ; Resguardo el manejador
    mov ebx, 1
    int 80h

    pop ebx
    cmp byte[buffer],10       ; Chequeo si llegue a fin de linea
    jne leerCaracter
    ret

imprimirLineasTotales

    push ebx
    push ecx
    push edx
    mov eax, 4
    mov ebx, 1
    mov ecx, [lineasTotales]
    mov edx, 4
    int 80h
    pop edx
    pop ecx
    pop ebx
    ret

avanzarLinea ; Actualiza los contadores para poder leer una linea mas

    push ebx
    mov ebx, [lineasConsola]
    inc ebx
    mov [lineasConsola], ebx
    pop ebx
    ret


avanzarPantalla ; Actualiza los contadores para poder leer una nueva pantalla

    push ebx
    mov ebx, [lineasConsola]
    add ebx, lineasPantalla
    mov [lineasConsola], ebx
    pop ebx
    ret

_start:

    pop ebx      ; argc 
    pop ebx      ; argv[0] 
    pop ebx      ; Nombre del archivo

    mov eax,5    ; sys_open
    mov ecx,0
    int 80h 

    mov ebx,eax  ; Muevo el puntero a ebx para leerlo
    test eax,eax    
    js  exite    ; Se produjo un error al intentar abrir el archivo

leerLinea:  

    call leerCaracter          ;imprimo una linea
    push eax                   ; Llegue al final de la linea, debo aumentar la cantidad de lineas leidas y chequear si llegue al tope de la consola
    push ebx
    mov eax, [lineasTotales]
    mov ebx, [lineasConsola]
    inc eax                    ; Lei una linea
    cmp eax, ebx               ; Chequeo si complete la pantalla
    mov [lineasTotales], eax
    pop ebx
    pop eax
    jl leerLinea                ; No llene la consola
    ;call imprimirLineasTotales ; Imprimir lineas leidas hasta el momento;no funciona
    call leerInput
    cmp byte[input],'s'
    jne seguir                  ;no presione la barra
    call avanzarLinea           ; Usuario presiono la barra
    jmp leerLinea

seguir:

    cmp byte[input], 'e'            ; Usuario presiono enter
    jne exite                   ; No es la barar ni salto de linea, se produce un error
    call avanzarPantalla
    jmp leerLinea

    mov ebx, 0      ; salgo sin errores
    mov eax, 1      ; sys_exit
    int 80h



final:

    call imprimirLineasTotales
    mov ebx, 0      ; salgo sin errores
    mov eax, 1      ; sys_exit
    int 80h

exite:

    mov ebx, 6      ; If there was an error, save the errno in ebx
    mov eax, 1      ; Put the exit syscall number in eax
    int 80h         ; Bail out
Jim Garrison
  • 85,615
  • 20
  • 155
  • 190
user2835994
  • 3
  • 1
  • 6
  • 1
    Please show what you have tried so far. – Jim Garrison Nov 17 '13 at 04:40
  • ok, i add it to op. Sorry that coments are in spanish and of course its not full. For example, my idea after leerInput it's call read line one more or "default" times, depends if user press spacebar or enter. Also i've to make a int to string so i can print how many lines i've read from file, and finally learn how to "move" the text in console like more comand does... Buy one thing at time, now im trying to focus on keypress – user2835994 Nov 17 '13 at 14:54
  • I edit againg. I tried to be more clear about whay i want to do. When programa read 's' and 'e' is simulating space and enter. Now i've another problem, after first 's' program should continue but finish, look like only call leerInput one time and then go for exite – user2835994 Nov 17 '13 at 16:54

3 Answers3

1

By default, when reading from a terminal in Linux (which includes any terminal window or remote login, or any interactive thing with an actual keyboard involved), the kernel will collect the characters typed in a buffer, processing backspaces and the like, until a newline is entered. Only after the newline will it send the data back to the user process in response to a read system call. This is called "canonical" input processing. If you want to avoid this, and read single characters immediately as they are typed, you need to put the terminal in non-canonical mode. In C, you can do this with the tcsetattr(3) function in the C library, which you may be able to call from your assembly program. If you're trying to avoid even the C library however, you can use raw ioctl(2) system calls.

For linux, the necessary information is in the termios(3) and tty_ioctl(4) manual pages.

Chris Dodd
  • 119,907
  • 13
  • 134
  • 226
0

Syscalls are what you're looking for, but without providing what you've tried, it's quite impossible to get into specifics of what you should be doing. Some general advice holds, though.

You can read one character at a time from terminal, which is just another file, using syscalls. Depending on the target architecture, namely the question is it 32- or 64-bit, you can find appropriate syscalls from unistd_32.h or unistd_64.h, most likely to lie in /usr/include/x86_64-linux-gnu/asm/ on your system.

The 32-bit syscalls take the syscall number in eax and arguments in ebx, ecx,edx, esi, edi and ebp. Setup those appropriately and do int 0x80.

The 64-bit syscalls take the syscall number rax and arguments in rdi, rsi, rdx, rcs, r8 and r9. Setup those appropriately and do syscall.

You might benefit from reading some other excellent Q&As on stackoverflow about assembly language programming on Linux. Actually, I think it could be taken as a recommended next step.

Community
  • 1
  • 1
  • thanks for your advice... Actually i've read a lot of examples, tutorials and faqs. I know how to read from console with sys_read, (im using 32bits linux) but in that case user have to press enter to continue. My finall objetive is make a small version of more comand, so i need to continue the execution of the program after user click spacebar or enter, but only one key – user2835994 Nov 17 '13 at 14:15
0

Without changing the mode from canonical to non canonical mode, think this is not possible. This is because when user enter's a character, they get buffered inside kernel and, depending on the mode of the tty/console they get delivered to reader either before '\n' or immediately.

Nithin
  • 191
  • 5