Author Topic: Assembly errors using windows.h in 64-bit NASM program  (Read 15038 times)

Offline paml27

  • Jr. Member
  • *
  • Posts: 37
Assembly errors using windows.h in 64-bit NASM program
« 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. 

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Assembly errors using windows.h in 64-bit NASM program
« Reply #1 on: January 11, 2018, 03:27:26 AM »
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

« Last Edit: January 11, 2018, 03:35:35 AM by Frank Kotler »

Offline dreamCoder

  • Full Member
  • **
  • Posts: 107
Re: Assembly errors using windows.h in 64-bit NASM program
« Reply #2 on: January 11, 2018, 02:50:17 PM »
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: 

Code: [Select]
%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).

Code: [Select]
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.

Offline paml27

  • Jr. Member
  • *
  • Posts: 37
Re: Assembly errors using windows.h in 64-bit NASM program
« Reply #3 on: January 11, 2018, 06:15:26 PM »
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? 



Offline dreamCoder

  • Full Member
  • **
  • Posts: 107
Re: Assembly errors using windows.h in 64-bit NASM program
« Reply #4 on: January 11, 2018, 07:14:31 PM »
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.

Code: [Select]
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).


« Last Edit: January 11, 2018, 07:19:46 PM by dreamCoder »

Offline dreamCoder

  • Full Member
  • **
  • Posts: 107
Re: Assembly errors using windows.h in 64-bit NASM program
« Reply #5 on: January 11, 2018, 07:42:17 PM »
I modified your code so it should work with GoLink

Code: [Select]
;;; 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.

Offline dreamCoder

  • Full Member
  • **
  • Posts: 107
Re: Assembly errors using windows.h in 64-bit NASM program
« Reply #6 on: January 11, 2018, 07:48:30 PM »
Another example, calling MessageBoxA from user32.dll.

Code: [Select]
;;; 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.


Offline paml27

  • Jr. Member
  • *
  • Posts: 37
Re: Assembly errors using windows.h in 64-bit NASM program
« Reply #7 on: January 11, 2018, 07:54:39 PM »
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.