2

I want to compile x64 app with simple MsgBox using Fasm. I've wrote the code, it compiles successfully, but when I run it nothing is shown and the program just ends. What's wrong?

format PE64 GUI 4.0
entry main

include 'win64a.inc'

main:
  invoke MessageBox,NULL,'Hello, World!','Fasm message box:',MB_OK
  invoke ExitProcess,0

library kernel32,'kernel32.dll',\
        user32,'user32.dll'

include 'api/kernel32.inc'
include 'api/user32.inc'

If try to debug in VS2017 I get an exception:

Вызвано исключение по адресу 0x0000000000001108 в program.exe: 0xC0000005: нарушение прав доступа при исполнении по адресу 0x0000000000001108.

If translate:

Exception at address 0x0000000000001108 in program.exe: 0xC0000005: access violation when executing address 0x0000000000001108.

Qwertiy
  • 19,681
  • 15
  • 61
  • 128
  • Maybe `invoke` doesn't do the right thing. Maybe it is assuming 32 bit for whatever reason. Maybe it is assuming stack alignment. Try adding a `push rbp` first thing in `main`. Anyway, you should learn to write code by hand before you start to use macros and even then be sure what each actually does. – Jester May 05 '20 at 21:18

1 Answers1

3

I'm marking this as community wiki so others can fill in a description of why this works. Of note is:

  • .idata section for imports
  • .text section that is executable
  • sub rsp, 8 (or equivalent like push rbp) for stack alignment per the Windows x86-64 calling convention.

The code:

include 'win64a.inc'

format PE64 GUI 4.0
entry main

section '.text' code readable executable
main:
  sub rsp, 8
  invoke MessageBox,NULL,'Hello, World!','Fasm message box:',MB_OK
  invoke ExitProcess,0

;section '.data' data readable writeable
; Data here

section '.idata' import data readable
library kernel32,'kernel32.dll',\
        user32,'user32.dll'

include 'api/kernel32.inc'
include 'api/user32.inc'
Michael Petch
  • 46,082
  • 8
  • 107
  • 198