等待用户输入而不输入linux x86汇编程序

时间:2013-11-17 04:04:56

标签: linux assembly x86

即时尝试在汇编程序中编程,我需要做一些事情,以便等待用户输入键(仅输入或空格)输入,如y / n选项。 我在dos中读了大约16h,它在linux中类似于sys_Call? 我还读到了关于禁用册选但看起来太复杂到诅咒级别 感谢

    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

3 个答案:

答案 0 :(得分:1)

默认情况下,当从Linux中的终端(包括任何终端窗口或远程登录,或涉及实际键盘的任何交互式事物)读取时,内核将收集在缓冲区中输入的字符,处理退格等等,直到输入换行符。只有在换行符之后,它才会将数据发送回用户进程以响应读取系统调用。这称为“规范”输入处理。如果要避免这种情况,并在键入时立即读取单个字符,则需要将终端设置为非规范模式。在C中,您可以使用C库中的tcsetattr(3)函数执行此操作,您可以从汇编程序中调用该函数。但是,如果您试图避免使用C库,则可以使用原始的ioctl(2)系统调用。

对于linux,必要的信息在termios(3)和tty_ioctl(4)手册页中。

答案 1 :(得分:0)

您正在寻找Syscalls,但如果没有提供您尝试过的内容,就很难了解您应该做些什么。但是,一些一般性建议仍然存在。

您可以使用系统调用从终端(这只是另一个文件)一次读取一个字符。根据目标体系结构,即问题是32位还是64位,您可以从unistd_32.hunistd_64.h找到适当的系统调用,最有可能位于系统上的/usr/include/x86_64-linux-gnu/asm/

32位系统调用采用eax中的系统调用号和ebx,ecx,edx,esi,edi和ebp中的参数。适当地设置并执行int 0x80。

64位系统调用采用rdi,rsi,rdx,rcs,r8和r9中的系统调用号rax和参数。适当地设置并进行系统调用。

您可能会从阅读有关assembly language programming on Linux的堆栈溢出的其他优秀Q& As中受益。实际上,我认为这可以作为推荐的下一步。

答案 2 :(得分:0)

如果不将模式从规范模式更改为非规范模式,请认为这是不可能的。这是因为当用户输入一个字符时,它们会在内核中缓冲,并且根据tty / console的模式,它们会在'\ n'之前或立即传送给阅读器。