Author Topic: Using sys_read to read a character into a byte in memory or a register  (Read 10107 times)

Offline Holden

  • New Member
  • Posts: 1
Hello. I am currently working on recreating a GetCh macro that retrieves a character from the user and can store that into either a general purpose register or a byte in memory. While it works with a location in memory, I can't really figure out how to write to a register without having a buffer to store it in temporarily. Furthermore, I don't really know how to make the macro discern between a register and a memory location.

This is for a macro file that can be included into another assembly file in order to have easy to use macros to handle various tasks for a school project. My knowledge of NASM is not well developed, and after COVID hit, the instruction has dropped in quality. So I'm asking for help here.

Here is what my code currently looks like.

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Hi Holder,

I'll post more in a minute... maybe... Here's what I use to get just one character... while I've got it at hand...

Later,
Frank

Code: [Select]
;-----------------------------
; ioctl subfunctions
%define TCGETS 0x5401 ; tty-"magic"
%define TCSETS 0x5402

; flags for 'em
%define ICANON 2 ;.Do erase and kill processing.
%define ECHO 8 ;.Enable echo.


    struc termios
alignb 4
.c_iflag: resd 1 ; input mode flags
.c_oflag: resd 1 ; output mode flags
.c_cflag: resd 1 ; control mode flags
.c_lflag: resd 1 ; local mode flags
.c_line: resb 1 ; line discipline
.c_cc: resb 19 ; control characters
    endstruc
;---------------------------------

getc:
    push ebp
    mov ebp, esp
   
    sub esp, termios_size     ; make a place for current kbd mode
   
    push edx
    push ecx
    push ebx
   
    mov eax, SYS_IOCTL        ; get current mode
    mov ebx, STDIN
    mov ecx, TCGETS
    lea edx, [ebp - termios_size]
    int 80h
   
                              ; monkey with it
    and dword [ebp - termios_size + termios.c_lflag], ~(ICANON | ECHO)

    mov eax, SYS_IOCTL
    mov ebx, STDIN
    mov ecx, TCSETS
    lea edx, [ebp - termios_size]
    int 80h
   
    xor eax, eax
    push eax         ; this is the buffer to read into
     
    mov eax, SYS_READ
    mov ebx, STDIN
    mov ecx, esp     ; character goes on the stack
    mov edx, 1       ; just one
    int 80h          ; do it
                     
                     ; restore normal kbd mode
    or dword [ebp - termios_size + termios.c_lflag], ICANON | ECHO
   
    mov eax, SYS_IOCTL
    mov ebx, STDIN
    mov ecx, TCSETS
    lea edx, [ebp - termios_size]
    int 80h
   
    pop eax          ; get character into al

    pop ebx          ; restore caller's regs
    pop ecx
    pop edx
   
    mov esp, ebp     ; leave
    pop ebp
    ret
;-------------------------


Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Hi again,

Doggone! I thought I replied to you yesterday. Said "welcome to the forum" and blah blah blah... Don't see it now. I hate it when that happens!

I pointed out that sys_read always waits for "enter" but that there's a way around that. See above. It is imperfect, but "seems to work".

I said you were in the right track. That may or may not be true. If you use a macro, all that code will be inserted into your program every time you use it. This may or may not be what you want.

Lessee... your "proc_getch" is called, but does not seem to "ret". That could be a problem.

Best,
Frank