即时尝试在汇编程序中编程,我需要做一些事情,以便等待用户输入键(仅输入或空格)输入,如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
答案 0 :(得分:1)
默认情况下,当从Linux中的终端(包括任何终端窗口或远程登录,或涉及实际键盘的任何交互式事物)读取时,内核将收集在缓冲区中输入的字符,处理退格等等,直到输入换行符。只有在换行符之后,它才会将数据发送回用户进程以响应读取系统调用。这称为“规范”输入处理。如果要避免这种情况,并在键入时立即读取单个字符,则需要将终端设置为非规范模式。在C中,您可以使用C库中的tcsetattr(3)函数执行此操作,您可以从汇编程序中调用该函数。但是,如果您试图避免使用C库,则可以使用原始的ioctl(2)系统调用。
对于linux,必要的信息在termios(3)和tty_ioctl(4)手册页中。
答案 1 :(得分:0)
您正在寻找Syscalls,但如果没有提供您尝试过的内容,就很难了解您应该做些什么。但是,一些一般性建议仍然存在。
您可以使用系统调用从终端(这只是另一个文件)一次读取一个字符。根据目标体系结构,即问题是32位还是64位,您可以从unistd_32.h
或unistd_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'之前或立即传送给阅读器。