I searched the internet rather, an example of a NASM x64 for windows, but I found just one, and, not work :(, just found for linux, code someone could show an example of how to create a Hello world NASM x64 windows
            Asked
            
        
        
            Active
            
        
            Viewed 3,398 times
        
    2
            
            
        - 
                    1It would be helpfull if you copied these "hello World" examples to the question, rather then just posting the links. I guess something like this can be usefull. – Devolus Dec 07 '13 at 19:29
- 
                    1http://forum.nasm.us has some win64 examples that might be useful. – Frank Kotler Dec 07 '13 at 21:14
- 
                    1What means "not work"? (Which error message / which behaviour / ...) – Martin Rosenau Dec 07 '13 at 21:40
2 Answers
1
            
            
        A topic talking about that : https://openclassrooms.com/forum/sujet/nasm-win64-bug-hello-world. Someone brings up a solution in NASM [Win64].
main.asm
extern GetStdHandle
extern WriteFile
extern Sleep
extern ExitProcess
 
%define STD_OUTPUT_HANDLE (-11)
 
section .data
hello_str db "Hello World", 13, 10
hello_size equ ($ - hello_str)
 
output_handle dq 0
 
section .text
 
global main
main:
    ;Aligne la pile
    and rsp, 0xFFFF_FFFF_FFFF_FFF0
    mov rbp, rsp
 
    ;Récupère l'output standart
    mov ecx, STD_OUTPUT_HANDLE
    call GetStdHandle
    mov [output_handle], rax
     
    ;Affiche le message
    ;Shadow Space
    sub rsp, 48
    mov rcx, [output_handle]
    mov rdx, hello_str
    mov r8d, hello_size
    mov r9, 0
    mov QWORD [rsp + 32], 0
    call WriteFile
    ;Détruit l'espace de pile alloué pour les paramètres de la fonction
    add rsp, 48
     
    ;Pause de 1000 millisecondes pour donner le temps de voir
    ;Shadow Space
    sub rsp, 0x20
    mov ecx, 1000
    call Sleep
     
    ;Quitte
    xor rcx, rcx
    call ExitProcess
make.bat
@echo off
 
nasm.exe -fwin64 main.asm -o Obj/main.o
gpp.exe -s -m64 Obj/main.o -o hello.exe C:\Windows\System32\kernel32.dll
 
pause
"Note that I link with g++, but I think you can adapt it to your linker."
 
    
    
        r0t0r
        
- 51
- 2
- 
                    1`GetStdHandle` follows the same calling convention as other functions; you should reserve shadow space (and the space you're going to need later) *before* calling it. Or not at all, since your `main` doesn't return (instead calling an exit function), just let main's own shadow space and return address get overwritten like you already did for `GetStdHandle`. It certainly doesn't make sense to keep adjusting RSP during the function, like `add rsp, 48` / `sub rsp, 0x20`. – Peter Cordes Jun 16 '21 at 10:46
- 
                    1Also, you should be using `default rel` so `mov rcx, [output_handle]` will use a RIP-relative addressing mode (more efficient than 32-bit absolute `[disp32]`). Or better, just use registers (or at least the stack; you even set up RBP as a frame pointer...), not static storage. e.g. `mov rcx, rax`, if file handles are really 64-bit in Windows. (Apparently all Windows Handles are 32-bit: [What is the range of a Windows HANDLE on a 64 bits application?](https://stackoverflow.com/q/18266626) so `mov ecx, eax` to zero-extend it into RCX) – Peter Cordes Jun 16 '21 at 10:51
- 
                    1Having every Windows programs do its own sleep or wait-for-input is kind of an anti-pattern. Developers should set up an environment where they run a command in an existing terminal, or a new terminal that stays open until manually closed. Or use a .bat or something to run a program and then pause. – Peter Cordes Jun 16 '21 at 11:18
- 
                    (I guess you just copied this code that someone else wrote, but now it's in your answer so it's your recommendation for a Hello World example.) – Peter Cordes Jun 16 '21 at 11:20
0
            
            
        I just wrote a minimal windows 64 assembly code file. I compile it with nasm and I link it with ld.exe. I am not an expert. I am learning but I have noticed a lack of a simple code file. Source asm file is:
    bits 64
default rel
MB_OK   equ 0
NULL    equ 0
extern MessageBoxA
extern ExitProcess
section .text
    push    rbp
    mov     rbp,    rsp
    
    mov     rcx,    MB_OK
    lea     rdx,    mensaje2
    lea     r8,     mensaje1
    mov     r9,     NULL
    sub     rsp,    32
    call    MessageBoxA
    
    
    xor     rcx,    rcx
    sub     rsp,    32
    call    ExitProcess
section .data
    mensaje1: db "Hola colega", 0
    mensaje2: db "Esto es una prueba", 0
I compile it with this makefile:
EXE=a.exe
ASMB=nasm.exe
LINK=ld.exe
ASMFLAGS=
LDFLAGS = -LC:\SinInstalacion\Desarrollo\mingw64\x86_64-w64-mingw32\lib -lkernel32 -luser32
OBJS=main.o
all: $(EXE)
$(EXE): $(OBJS)
    $(LINK) -o $(EXE) $(OBJS) $(LDFLAGS)
    
%.o: %.asm
    $(ASMB) -f win64 $< -o $@ $(ASMFLAGS)
clean:
    del $(OBJS) $(EXE)
I wrote this post because I have not found an example in Google.
Forgive my mistakes.
Cheers.
I needed to add debug information to the exe file to be debugged with gdb. I changed makefile to:
EXE=a.exe
ASMB=nasm.exe
LINK=ld.exe
ASMFLAGS=-g -F dwarf
LDFLAGS =-g -LC:\SinInstalacion\Desarrollo\mingw64\x86_64-w64-mingw32\lib -lkernel32 -luser32
OBJS=main.o
all: $(EXE)
$(EXE): $(OBJS)
    $(LINK) -o $(EXE) $(OBJS) $(LDFLAGS)
    
%.o: %.asm
    $(ASMB) -f elf64 $< -o $@ $(ASMFLAGS)
clean:
    del $(OBJS) $(EXE)
I hope it could be useful.
 
    
    
        José Antonio López Cano
        
- 166
- 1
- 4
- 
                    For debugging asm, I usually use `layout asm` or `layout reg` / `layout next`, so GDB is disassembling the machine code, not showing me the source file. Then it doesn't need debug info, just the symbols. (Also, DWARF debug info in a PE / COFF executable? I thought Windows would have its own debug-info format to go with its non-ELF object-file / executable format. But if GDB understands it, then cool.) – Peter Cordes Sep 01 '23 at 21:37
- 
                    Standard NASM syntax for `lea rdx, mensaje2` is `lea rdx, [mensaje2]`. Without the square brackets, it's only supported because of NASM 2.15 or 2.16's MASM-compatibility changes that make LEA special for this. (https://nasm.us/doc/nasmdoc6.html#section-6.5) LEA needs a memory source operand, not an immediate, and a symbol name without square brackets is normally an immediate. ([Basic use of immediates vs. square brackets in YASM/NASM x86 assembly](https://stackoverflow.com/q/10362511)). But yes, with `default rel` (good), and recent NASM, you get `lea rdx, [rel mensaje2]` – Peter Cordes Sep 01 '23 at 21:42
- 
                    You don't need (and shouldn't do) `sub rsp, 32` before *every* call. Do it once at the top of the function to reserve shadow space that will get reused for each callee. RSP needs to be 16-byte aligned before a `call` (so functions can assume RSP%16 == 8 on function entry), so whether you sub `16*n + 8` or `16*n` depends on whether you did an even or odd number of pushes on function entry. Other than alloca / VLAs, RSP shouldn't move except in the function prologue. – Peter Cordes Sep 01 '23 at 21:46
 
    