Quantcast
Channel: Ubuntu 18.04.3 LTS get terminal columns and rows NASM - Code Review Stack Exchange
Viewing all articles
Browse latest Browse all 5

Ubuntu 18.04.3 LTS get terminal columns and rows NASM

$
0
0

As part of the prologue of all my console applications, I need to determine the extents of the current terminal so if there are less than 132 columns or 43 lines the user can be warned output may not appear as expected. Code has been tested with;

$ AppName /usr/include/*.h

Assemble withsource being whatever name you want to give app.

~$ nasm -felf64 source.asm -source.o   ~$ ld -osource -osource

which passes 112 arguments to process.

Essentially what I am going for is contiguous flow with the least number ofinstructions. Time is an important consideration but it is the least important especially considering if my calculations are near correct, this procedure comes in at 4.18 micro seconds.

   USE64   global   _start        section .text       ; *----*  *----* *----* *----* *----* *----* *----* *----* *----* *----* *----*  _start:    %define argc    [rbp+ 8]    %define args    [rbp+16]        mov     rsi, rsp        ; Establish pointer to argc.        push    rbp             ; So argc & **args can easily be addressed        mov     rbp, rsp        ; via base pointer.; This application expects a minimum 132 x 43 terminal. If this sessions metrics;  are less than that, then operator needs to be made aware output to screen; may not be as expected.   ; [A] Establish a pointer to the array of QWORD pointers to environment   ;      strings. It is determined by &argc + (argc+1) * 8        lodsq                   ; Determine # of args passed via command-line        inc     eax             ; Bump argument count        shl     rax, 3          ; Multiply by 8        add     rsi, rax        ; Add result to &argc   ; [B] Intialize the two registers needed for the loop that determines   ;     matching entries.        mov     edi, Metrics    ; Pntr to the two strings that need to be found.    ; RDX Bits  07 - 00 = Count of environment variables.    ;           15 - 08 = Columns defined by "COLUMNS=".    ;           23 - 16 =    Rows    """LINES=".        xor     edx, edx        mov     ecx, edx        ; Should be zero, but just to be safe.  FindMatch:        lodsq                   ; Get pointer to next environment string.        test    eax, eax        ; NULL pointer indicates end of array.        jnz     .cont   ; Now RBP - 1 = Count of environment strings   ;     RBP - 2 = Current display columns   ;     RBP - 3 =                 rows        mov     [rbp-4], edx        jmp     .done   .cont:        inc      dl             ; Bump count of environment strings.        mov     ecx, 6          ; Length of string first string.        mov      bl, [rax]      ; Get first character.   ; Determine if this string begins with either 'L' or 'C'.        cmp       bl, 'L'        jz      .cmpstr        cmp       bl, 'C'        jnz     FindMatch        push    rdi        add     edi, ecx        ; Bump to point to next string        add      cl, 2          ; and it is 2 characters longer        jmp     .cmpstr + 1     ; No need to save RDI again   ; Now that the first character matches, determine if the remaining   ; do for a count of CL   .cmpstr:        push    rdi        push    rsi        mov     rsi, rax        ; Move pointer to string into source index.        repz    cmpsb           ; Compare strings for count of CL.        jnz     .nextone        ; Does not match? Carry on.        mov     rax, rcx        ; Both registers are NULL now.   .L0: lodsb                   ; Read ASCII decimal digit.        test    eax, eax        jz      .J0   ; Convert ASCII decimal digits to binary. As it is safe to assume we will   ;  only be expecting characters '0' - '9', this works quite effectively.        and      al, 15         ; Strip high nibble        imul    ecx, 10        add     ecx, eax        jmp     .L0   ; Determine which position result will be written based on which   ; calculation was done   .J0: shl     ecx, 16         ; Assume value is # of rows.        cmp     byte [rdi], 0        jnz     $ + 5        shr     ecx, 8          ; Move back into columns position.        or      edx, ecx        ; Copy to appropriate position in RDX    .nextone:        pop     rsi        pop     rdi             ; Restore pointer to array of pointers.        jmp     FindMatch    .done:        shr     edx, 8        sub      dx, 0x2b84     ; Equivalent to DH = 43 & DL = 132        test     dx, 0x8080     ; Result equal negative in either 8 bit register        jz      ParseCmdLine    ; TODO -> Put some kind of prompting here for user to respond too.  ParseCmdLine:    ; TODO -> Implement something similar to optarg.  Exit:        leave                   ; Kill empty procedure frame        xor     edi, edi        ; Set return code EXIT_SUCCESS        mov     eax, sys_exit        syscall                 ; Terminate application    section .rodata; =============================================================================  Metrics   db  'LINES='            db  'COLUMNS=',0,0  ; So next is page aligned.

Viewing all articles
Browse latest Browse all 5

Latest Images

Trending Articles





Latest Images