Assembly language examples using NASM on Windows

Console Message - 64 bit

Output a message to the console window, 64 bit.



Open a console window and run the executable.

WriteFile takes 5 parameters. The 5th is placed on to the stack.

WriteFile was chosen as the output can be redirected to a file using > filename.
A string length needs to be supplied, in this case, by looping over the string until a 0 is found.
For buffer overrun protection, there are a maximum number of loops. If you alter the message text, don't forget to change this value (21).

WriteConsoleA could replace WriteFile, as this takes a null terminated string directly, so a length is not needed.
The downside is, the output can't be redirected to a file.


                                                ; Console Message, 64 bit. V1.01
NULL              EQU 0                         ; Constants

extern GetStdHandle                             ; Import external symbols
extern WriteFile                                ; Windows API functions, not decorated
extern ExitProcess

global Start                                    ; Export symbols. The entry point

section .data                                   ; Initialized data segment
 Message db "Console Message 64", 0Dh, 0Ah, 0

section .bss                                    ; Uninitialized data segment
alignb 8
 StandardHandle resq 1
 Written        resq 1

section .text                                   ; Code segment
 and   RSP, 0FFFFFFFFFFFFFFF0h                  ; Align the stack to a multiple of 16 bytes

 sub   RSP, 32                                  ; 32 bytes of shadow space
 call  GetStdHandle
 mov   qword [REL StandardHandle], RAX
 add   RSP, 32                                  ; Remove the 32 bytes

 lea   RSI, [REL Message]
 xor   RDI, RDI

.LengthLoop:                                    ; Find the string length by searching for
 cmp   byte [RSI + RDI], 0                      ; the null terminator
 je    .LengthDone

 add   RDI, 1                                   ; Maximum length, prevents buffer overrun
 cmp   RDI, 21                                  ; if there is no null terminator
 jne   .LengthLoop

 sub   RSP, 32 + 8 + 8                          ; Shadow space + 5th parameter + align stack
                                                ; to a multiple of 16 bytes
 mov   RCX, qword [REL StandardHandle]          ; 1st parameter
 lea   RDX, [REL Message]                       ; 2nd parameter
 mov   R8, RDI                                  ; 3rd parameter
 lea   R9, [REL Written]                        ; 4th parameter
 mov   qword [RSP + 4 * 8], NULL                ; 5th parameter
 call  WriteFile                                ; Output can be redirect to a file using >
 add   RSP, 48                                  ; Remove the 48 bytes

 xor   RCX, RCX
 call  ExitProcess