Author Topic: WIN64 program crashes  (Read 7814 times)

Offline Developer

  • Jr. Member
  • *
  • Posts: 5
WIN64 program crashes
« on: February 17, 2013, 10:15:36 AM »
Hi,
I am using windows 7 and I'm trying to make a little x64 application. Compiling works fine and linking with GoLink also returns no error, but the result executable crashes when it's started.
What's wrong with my code or is the way I'm linking/compiling this wrong?

Code: [Select]
[BITS 64]

extern ExitProcess
extern MessageBoxA

segment .data
Caption db 'Caption Text',0
Text db "My MessageBox Text.",0

segment .code
global _start
_start:
push dword 0
push qword Caption
push qword Text
push qword 0
call [MessageBoxA]

push dword 0
call [ExitProcess]

Code: [Select]
nasm -fwin64 -otest.obj test.asm
golink /fo test.exe /entry _start kernel32.dll user32.dll test.obj

Thx for help,
Developer  :)

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2461
  • Country: us
Re: WIN64 program crashes
« Reply #1 on: February 17, 2013, 11:52:13 AM »
I'm pretty clueless on 64-bit, but in 32-bit, using "-f obj", if we do:
Code: [Select]
extern Exitprocess
import Exitprocess kernel32.dll
... and link it with Alink, then we have to do:
Code: [Select]
call [ExitProcess]

"Ordinarily", we'd do:
Code: [Select]
call ExitProcess
(same applies to other APIs, of course) I don't know why this oddity with "-f obj" and "import", but I suspect that's your problem.

I would suggest eliminating the square brackets on your calls. I would also suggest changing "segment .code" to "segment .text", as ".text" is the "known" name. I think that matters less - ".code" is probably okay.

See if that helps...

Best,
Frank


Offline Gerhard

  • Jr. Member
  • *
  • Posts: 50
Re: WIN64 program crashes
« Reply #2 on: February 17, 2013, 01:14:41 PM »
Hi Developer

your code won't work. Under Windows 64 bit, function parameters are not passed via stack, but via registers. You should check, for example, the following net ressources: http://msdn.microsoft.com/en-us/library/7kcdt6fy.aspx and http://yankeerino.com/windowsx64callingconvention.bhs.

Gerhard

Offline Gerhard

  • Jr. Member
  • *
  • Posts: 50
Re: WIN64 program crashes
« Reply #3 on: February 17, 2013, 04:06:10 PM »
Hi Developer,

I've attached a working 64 bit Windows example for you.

Code: [Select]
        [BITS 64]                        ; 64 bit segment

        global Start                     ; visibility for linker

        extern ExitProcess               ; externals
        extern MessageBoxA


        segment .data                    ; initialized data

wtxt    db 'Hallo 64 bit Windows Assembly Language World!', 0
wcapt   db 'The usual Hallo Example', 0

        segment .text                    ; code

Start:

        ; make room for arguments + 16 bit aligned stack

        sub        rsp, 40
        xor        r9, r9                ; r9d  = uType
        mov        r8, wcapt             ; r8  -> lpCaption
        mov        rdx, wtxt             ; rdx -> lpText
        xor        rcx, rcx              ; rcx = hWnd
        call       MessageBoxA
        xor        ecx, ecx              ; ecx = exit code
        call       ExitProcess
The example is linked with GoLink to the running EXE. Check for details the included file build_messagebox.bat. It runs with Windows 7, SP1. I hope that'll help you a bit and will give you right direction.

Gerhard

Offline Developer

  • Jr. Member
  • *
  • Posts: 5
Re: WIN64 program crashes
« Reply #4 on: February 17, 2013, 04:39:32 PM »
Hi Gerhard,

thank you for the example, it works pretty well on my computer :). I guess I'll have to take a look at the 64bit registers and at the calling conventions.
If there come more questions in my mind, I may ask again.

Developer

Offline Gerhard

  • Jr. Member
  • *
  • Posts: 50
Re: WIN64 program crashes
« Reply #5 on: February 17, 2013, 05:35:57 PM »
Hi Developer,

thank you for the example, it works pretty well on my computer :).

you're welcome.  8)

I guess I'll have to take a look at the 64bit registers and at the calling conventions. If there come more questions in my mind, I may ask again.

That's an excellent idea. Please have in mind that the Linux and MacOS ABI for 64 bit are very different from Windows. So, it's very hard to develop for both worlds in parallel. You can use common code only in rare cases. That makes things very difficult.

Gerhard

Offline Gerhard

  • Jr. Member
  • *
  • Posts: 50
Re: WIN64 program crashes
« Reply #6 on: February 17, 2013, 06:36:16 PM »
Hi  Developer,

I've attached another example for Windows (64 bit).

Gerhard

Offline Developer

  • Jr. Member
  • *
  • Posts: 5
Re: WIN64 program crashes
« Reply #7 on: February 18, 2013, 04:54:01 PM »
Hey.. thank you ;)
I'll take a look at it.

Developer

Offline Gerhard

  • Jr. Member
  • *
  • Posts: 50
Re: WIN64 program crashes
« Reply #8 on: February 18, 2013, 07:09:20 PM »
Hi Developer,

Hey.. thank you ;)
I'll take a look at it.

Developer

that's okay. If you should have more questions, drop me a line. Have fun.

Gerhard

Offline Developer

  • Jr. Member
  • *
  • Posts: 5
Re: WIN64 program crashes
« Reply #9 on: February 20, 2013, 04:18:56 PM »
Hey, I'm back ;D

Why do I have to do the following?

Code: [Select]
; make room for arguments + 16 bit aligned stack
sub        rsp, 40

I read on http://yankeerino.com/windowsx64callingconvention.bhs:
Quote
In both cases the Windows convention demands the stack to be 16 byte aligned.
Ok, so I make room for 16 bytes. But why do I have to make room for arguments when I actually put the arguments in the registers and not on the stack?

Developer

Offline Gerhard

  • Jr. Member
  • *
  • Posts: 50
Re: WIN64 program crashes
« Reply #10 on: February 20, 2013, 04:53:34 PM »
Hi Developer,

Ok, so I make room for 16 bytes. But why do I have to make room for arguments when I actually put the arguments in the registers and not on the stack?

Developer

good question; you'll find the answer here: http://blogs.phoenix.com/phoenix_technologies_bios/2010/07/bios-undercover-calling-c-from-asm-in-x64.html. I hope that helps.

Gerhard

Offline Rob Neff

  • Forum Moderator
  • Full Member
  • *****
  • Posts: 430
  • Country: us
Re: WIN64 program crashes
« Reply #11 on: February 20, 2013, 05:08:04 PM »
But why do I have to make room for arguments when I actually put the arguments in the registers and not on the stack?

http://msdn.microsoft.com/en-us/library/ms235286.aspx

Offline Developer

  • Jr. Member
  • *
  • Posts: 5
Re: WIN64 program crashes
« Reply #12 on: February 20, 2013, 06:36:10 PM »
Thanks for your answers  :)

So, I tried to write a little function myself. It works but is also the right way to use/do it?

Code: [Select]
[bits 64]

extern MessageBoxA, ExitProcess

segment .data
Caption db "Message Box",0
Text1 db "Message 1!",0
Text2 db "Message 2!",0

segment .text
DoubleMsg:
; add argument space
sub rsp, 32

; call messagebox with current register arguments
call MessageBoxA

; receive arguments from stack
mov rcx, [rsp+64+32]
mov rdx, [rsp+64+24]
mov r8, [rsp+64+16]
mov r9, [rsp+64+8]

; call messagebox
call MessageBoxA

; free space
add rsp, 32

; return
ret

Start:
; 16 byte alligned stack
sub rsp, 16

; mov 4 arguments to the registers
mov rcx, 0
mov rdx, Text1
mov r8, Caption
mov r9, 0

; push another 4 arguments on the stack
push 0
push Text2
push Caption
push 0

; make room
sub rsp, 32

; call function
call DoubleMsg

; exit application
mov rcx, 0
call ExitProcess

I'll be happy about any idea for improvement ;)

Developer
« Last Edit: February 21, 2013, 12:56:00 PM by Developer »