NASM - The Netwide Assembler

NASM Forum => Example Code => Topic started by: TightCoderEx on May 08, 2012, 05:34:40 PM

Title: Display string on console 64 bit using SYSCALL
Post by: TightCoderEx on May 08, 2012, 05:34:40 PM
Coincidentally, the two versions of this are exactly the same size in bytes


Code: [Select]
global _start

; =========================================================================================================
section .data

  Prompt db 10, 'Hello Cruel World!', 10, 0
 
section .text
; =-= =-= =-= =-= =-= =-= =-= =-= =-= =-= =-= =-= =-= =-= =-= =-= =-= =-= =-= =-= =-= =-= =-= =-= =-= =-=
    ; Dispaly applications signon message

 _start: enter 24, 0 ; Create dummy frame

mov rsi, Prompt
call Console

     .Exit: leave ; Kill dummy frame
     
      xor rax, rax
      mov rdi, rax ; Exit status NULL
      mov al, SYS_EXIT
      syscall



Code: [Select]
; =========================================================================================================
; Display ASCII string on console (monitor)

; ENTRY: RSI = Pointer to null terminated string to be displayed.

; LEAVE: RAX = Bytes displayed excluding null.
;       All other registers preseved.

; FLAGS: ZR = 1 If nothing was displayed.
;    30H - 48 Bytes
; ---------------------------------------------------------------------------------------------------------

Console: push rdi
push rcx
push rdx

; First order of business is to search for end of string (NULL). Why? because we don't always
; know because there are times where strings are being built at runtime and this would have
; to be done anyway.

xor rcx, rcx
dec rcx ; Should be sufficiently large enough
mov al, 0 ; Byte we are search for
mov rdi, rsi
repnz scasb ; Find terminating character
neg rcx
dec rcx
dec rcx ; This is the actual length of string excluding null

; Setup registers for syscall

xor rax, rax
mov al, STDOUT ; I do this like this becuase it uses 5 bytes
mov rdi, rax ; versus mov RDI, STDOUT would take 11
mov al, SYS_WRITE
mov rdx, rcx ; Move count of bytes
syscall

pop rdx
pop rcx
pop rdi

or rax, rax
ret ; Return with string size in RAX and ZR=1 if string empty.
Title: Re: Display string on console 64 bit using SYSCALL
Post by: TightCoderEx on December 23, 2012, 07:15:12 PM
Essentially, this version is the same as the previous except a little extra functionality and being 8 bytes smaller.  I'm beginning to utilize sign extension as much as possible this eliminating REX prefix.
 
Code: [Select]
SYS_WRITE       equ      1
       STDOUT equ 1

global Show

; ENTER: RSI = Pointer to string to be displayed

; LEAVE: RAX = Strings length including terminator
;     = 1 Equivalent to NULL string

; RSI = Points to next avaliable string (assuming there is one)

section .text

          Show push rdi
push rdx ; Preserve
push rcx

; Find EOS

or ecx, -1 ; Should be big enough
mov rdi, rsi ; RDI needs to be pointer
mov al, 0
repnz scasb ; Search for EOS
neg ecx
sub ecx, 2
push rdi ; We'll need this later
jz .ZeroStr

; Display string. ARG2 : Passed by caller

mov rdx, rcx ; ARG3 : character count
mov eax, STDOUT
mov rdi, rax ; ARG1 : file descriptor
syscall

; Setup registers for return to caller

      .ZeroStr inc eax ; Bump over terminator
pop rsi ; Restore pointer to next position

pop rcx
pop rdx ; Retrieve
pop rdi

ret