NASM - The Netwide Assembler
NASM Forum => Programming with NASM => Topic started by: paml27 on January 11, 2018, 02:30:50 AM
-
I have a simple Windows program in NASM 64 (my first Windows API program in x64 -- I'm migrating from 32-bit MASM). I need windows.h to assemble this. I'm using Windows 7.
Windows has windows.h in a lot of different folders, all under C:\Program Files (x86). For this example, I used the windows.h file in C:\Program Files (x86)\Windows Kits\8.1\Include\um. However, the x86 folder is for 32-bit programs, but there is no windows.h file in the Program Files folder (for 64-bit).
When I assemble this with NASM, it outputs a long list of errors in the windows.h file. If I don't include windows.h, it will not recognize the externs (no surprise).
I thought NASM could only include a .inc file, but apparently there is no windows.inc.
Here is the source code:
%include "windows.h"
global main
extern GetStdHandle
extern WriteFile
section .text
main:
mov rcx, 0fffffff5h
call GetStdHandle
mov rcx, rax
mov rdx, NtlpBuffer
mov r8, [NtnNBytesToWrite]
mov r9, NtlpNBytesWritten
sub rsp, 40
mov dword [rsp + 32], 00h
call WriteFile
add rsp, 40
ExitProgram:
xor eax, eax
ret
section .data
NtlpBuffer: db 'Hello, World!', 00h
NtnNBytesToWrite: dq 0eh
section .bss
NtlpNBytesWritten: resd 01h
Any ideas are most appreciated. Thanks.
-
There is a program intended to convert C language ".h" files to ".inc" files suitable for Nasm:
https://sourceforge.net/projects/h2incn/
I don't know if it is in a usable condition. It might be worth a try.
The "nasmx" project may contain ".inc" files for Windows...
https://sourceforge.net/projects/nasmx/
Good luck!
Best,
Frank
-
I have a simple Windows program in NASM 64 (my first Windows API program in x64 -- I'm migrating from 32-bit MASM). I need windows.h to assemble this. I'm using Windows 7.
Windows has windows.h in a lot of different folders, all under C:\Program Files (x86). For this example, I used the windows.h file in C:\Program Files (x86)\Windows Kits\8.1\Include\um. However, the x86 folder is for 32-bit programs, but there is no windows.h file in the Program Files folder (for 64-bit).
When I assemble this with NASM, it outputs a long list of errors in the windows.h file. If I don't include windows.h, it will not recognize the externs (no surprise).
I thought NASM could only include a .inc file, but apparently there is no windows.inc.
Here is the source code:
%include "windows.h"
global main
extern GetStdHandle
extern WriteFile
section .text
main:
mov rcx, 0fffffff5h
call GetStdHandle
mov rcx, rax
mov rdx, NtlpBuffer
mov r8, [NtnNBytesToWrite]
mov r9, NtlpNBytesWritten
sub rsp, 40
mov dword [rsp + 32], 00h
call WriteFile
add rsp, 40
ExitProgram:
xor eax, eax
ret
section .data
NtlpBuffer: db 'Hello, World!', 00h
NtnNBytesToWrite: dq 0eh
section .bss
NtlpNBytesWritten: resd 01h
Any ideas are most appreciated. Thanks.
For this simple console code, you don't need any include file. It should run as it is without any include, given that you're using GCC 64 as the linker (or GoLink by linking to kernel32.dll).
gcc -m64 yoursource.obj -o yoursource.exe
In 64-bit, using WinAPI includes is often avoidable. You just need to look for the correct equates and constants values.
p/s GetStdHandle also requires shadow space.
-
Thanks, dreamCoder.
I tried to assemble it without the include file and I get the error "The following symbols were not defined in the object file: GetStdHandle WriteFile." That may be because I don't have a PATH directive to the linker (I'm using GoLink as the linker), but I don't know what path to use. Windows.h appears in a number of locations.
What path do you use?
-
I don't use / set any PATH at all. GoLink has its own way in finding "kernel32.dll". GCC calls it by default. I don't use any include.
golink /console yoursource.obj kernel32.dll
That's about it when using GoLink.
EDIT: Ofc you need to specify "start" as the default entry point. You probably need to call ExitProcess as well, replacing "ret", since from what I see, you have a GCC setup source (main, ret).
-
I modified your code so it should work with GoLink
;;; nasm -f win64 prog.asm
;;; golink /console prog.obj kernel32.dll
global start
extern GetStdHandle
extern WriteFile
extern ExitProcess
section .text
start:
sub rsp,40
mov rcx, 0fffffff5h
call GetStdHandle
mov rcx, rax
mov rdx, NtlpBuffer
mov r8, [NtnNBytesToWrite]
mov r9, NtlpNBytesWritten
mov dword [rsp + 32], 00h
call WriteFile
ExitProgram:
xor eax, eax
mov ecx,0
call ExitProcess
section .data
NtlpBuffer: db 'Hello, World!', 00h
NtnNBytesToWrite: dq 0eh
section .bss
NtlpNBytesWritten: resd 01h
That's it. Should work out of the box.
-
Another example, calling MessageBoxA from user32.dll.
;;; nasm -f win64 prog.asm
;;; golink prog.obj kernel32.dll user32.dll
global start
extern MessageBoxA
extern ExitProcess
section .text
start:
sub rsp,40
mov r9,0
mov r8,ttle
mov rdx,Msg
mov rcx,0
call MessageBoxA
ExitProgram:
xor eax, eax
mov ecx,0
call ExitProcess
section .data
ttle db 'MsgBox',0
Msg db 'Hello World',0
NASM is much easier than you thought :D
Hope this helps.
-
Hi, dreamCoder,
I was doing some additional research before I saw your three replies, and I came to the same conclusion, so I revised my GoLink command string to include kernel32.dll:
GoLink Win_API_Program.obj /dll msvcrt.dll kernel32.dll
and now it works as originally written. But of course I'll need to include shadow space, as you mentioned.
Thanks very much for your replies, and also thanks to Frank Kotler for the heads-up on NASM-X.