0 Replies - 958 Views - Last Post: 23 October 2019 - 02:52 AM

#1 TightCoderEx   User is offline

  • New D.I.C Head
  • member icon

Reputation: 1
  • View blog
  • Posts: 3
  • Joined: 01-December 12

Ubuntu 18.04.3 LTS getenv(..) equivalent without STDLIB or STDIO

Posted 23 October 2019 - 02:52 AM

Most of my programs are predicated upon a minimum terminal size of 132 x 43. In the event this criteria isn't met, I'd like to warn the user that output may not be as expected. To that end, the environment strings need to be read to glean what the current metrics are.

Code has been tested with and without command-line arguments.

$AppName /usr/include/* yields 112 arguments and procedure worked as expected.

Written using NASM 2.13.02 and linked with LD 2.30
   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 agruments 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		; Pointer 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	ParseCmdLine
  	
   .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
  	add	 cl, 2
  	jmp	.cmpstr + 1
  	
   ; 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		; Don't 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'll only be working
   ; with 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
  	
  ParseCmdLine:  
  	nop
  	
  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.



Is This A Good Question/Topic? 0
  • +

Page 1 of 1