Author Topic: Help with Hello World and NASM on mingw64  (Read 696 times)

Offline smaudet

  • Jr. Member
  • *
  • Posts: 4
Help with Hello World and NASM on mingw64
« on: November 25, 2018, 12:47:00 AM »
Hello all.

So I was trying to learn the NASM assembler a bit more, my end goal is to be able to try to load some library and be able to call it with arbitrary arguments, in particular problably kernel32.dll (I don't know if its even possible yet)...

Anyways, I'm faced with a much more immediate problem, I can't get Hello World to work on windows with the nasm compiler and the gcc linker. I'm using MSYS2's variant of MINGW64, and I've the following code:

; ----------------------------------------------------------------------------
; helloworld.asm
;
; This is a Win32 console program that writes "Hello, World" on one line and
; then exits.  It needs to be linked with a C library.
; ----------------------------------------------------------------------------

; https://forum.nasm.us/index.php?topic=810.0 ???

global  main
extern  printf

section .text

main:
    push    message
    call    printf
    ; add     esp, 4
    ; call    ExitProcess
    ret
message:
    db  'Hello, World', 10, 0

I'm using the following:

nasm -f win64 -o win-nasm.obj win-nasm.asm
gcc -o win-nasm.exe win-nasm.obj

This produces a win-nasm.exe which promptly proceeds to segfault as soon as I attempt to run it.

I can get a Hello World to work from nasm but it has to be linked with golink (and it uses kernel32 directly) and it needs to be run from a command prompt. Does anyone know what I'm missing here?

Offline dreamCoder

  • Full Member
  • **
  • Posts: 106
Re: Help with Hello World and NASM on mingw64
« Reply #1 on: November 25, 2018, 12:56:18 PM »
1) You're compiling 32-bit source with NASM's "win64" switch
2) You're linking without being explicit of either "-m32" or "-m64" switch, according to #1.
3) You're linking to multiple libraries... "printf" belongs to GCC by default... "ExitProcess" belongs to "kernel32.dll". "printf" could also belong to "msvcrt.dll". Which one?
4) For GCC32 bit, you should know a thing or two about C calling convention and C general structure. 

Here's a recent example... closest to what you are asking
https://forum.nasm.us/index.php?topic=2475.0

Offline smaudet

  • Jr. Member
  • *
  • Posts: 4
Re: Help with Hello World and NASM on mingw64
« Reply #2 on: November 25, 2018, 11:08:57 PM »
1) What is 32 bit about it? the only explicitly 32 bit thing I see is the line that's commented out.
2) 32 bit won't even link. I verified -fwin64 means 64 bit code, not 32 (I know windows has this weird WOWSYS64 thing which is 32 bit, I don't think that's relevant here). -m64 corresponds to -fwin64, -m32 to -fwin32
3) I'm not using ExitProcess. Its commented out...I have a ret and I did also try with push 0. I'm not sure where/what printf is, nor how to specify that.
4) Link? I don't think I'm doing anything special here, I'm putting a string pointer on the stack and then invoking the C ABI?

That recent example is only dealing with the kernel calls and MSVC.... I'm specifically trying to figure out why mingw64 won't compile.

Worth saying the 64 bit stuff compiles and segfaults, the 32 bit stuff seems to get very confused.


Offline dreamCoder

  • Full Member
  • **
  • Posts: 106
Re: Help with Hello World and NASM on mingw64
« Reply #3 on: November 26, 2018, 06:40:17 AM »
It's a 32-bit code.

push message
call printf
add esp,4

is a 32-bit CDECL or C calling convention. For 64-bit code, it is different entirely. Using "push" indicates it is a 32-bit code. And should not be compiled with "-f win64" switch. And for that, choosing the right linking switches is crucial.
Code: [Select]
        extern printf
        extern scanf

        section .data
prmpt1: db 'Enter an integer: ',0
prmpt2: db 'Your integer is %lld',0ah,0
format: db '%lld',0
value:  dq 0

        section .text
global main
main:
        sub     rsp,40          ;stack alignment + shadow space

        mov     rcx,prmpt1
        call    printf

        mov     rdx,value
        mov     rcx,format
        call    scanf

        mov     rdx,qword[value]
        mov     rcx,prmpt2
        call    printf

        add     rsp,40
        ret

; nasm -f win64 myprog.asm
; gcc -m64 myprog.obj -s -o myprog.exe

At this point, I am not sure what exactly you want. The whole picture you're trying to give me is that you're using 32-bit code and 32-bit calling convention, compiled into 64-bit binary format (which is PE32+ instead of PE), using 32-bit linking switch.. Is that what you're trying to do? You need to make up your mind. 

EDIT: Added full 64-bit code and put them in a code tag
« Last Edit: November 26, 2018, 07:39:23 AM by dreamCoder »

Offline dreamCoder

  • Full Member
  • **
  • Posts: 106
Re: Help with Hello World and NASM on mingw64
« Reply #4 on: November 26, 2018, 06:59:37 AM »
Just in case you actually need to compile a 32-bit code, use this
Code: [Select]
        extern _printf
        extern _scanf

        section .data
prmpt1: db 'Enter an integer: ',0
prmpt2: db 'Your integer is %d',0ah,0
format: db '%d',0
value:  dd 0

        section .text
        global _WinMain@16

_WinMain@16:
        push    ebp
        mov     ebp,esp

        push    prmpt1
        call    _printf
        add     esp,4*1

        push    value
        push    format
        call    _scanf
        add     esp,4*2

        push    dword[value]
        push    prmpt2
        call    _printf
        add     esp,4*2

        mov     esp,ebp
        pop     ebp
        ret

; nasm -f win myprog.asm
; gcc -m32 myprog.obj -s -o myprog.exe

Calling convention makes a huge difference in the way you compile and link your code.

EDIT: I gave you a full 32-bit example and put them in a code tag.
« Last Edit: November 26, 2018, 07:27:57 AM by dreamCoder »

Offline smaudet

  • Jr. Member
  • *
  • Posts: 4
Re: Help with Hello World and NASM on mingw64
« Reply #5 on: November 26, 2018, 11:30:15 AM »
Thanks for the clarification.

Code: [Select]
; ----------------------------------------------------------------------------
; win-nasm-64.asm
;
; This is a Win64 console program that writes "Hello, World" on one line and
; then exits.  It needs to be linked with a C library.
; nasm -o win-nasm-64.obj -fwin64 win-nasm-64.asm && gcc -m64 win-nasm-64.obj -o win-nasm-64.exe
; ----------------------------------------------------------------------------

global  main
extern  printf

section .text

main:
    sub     rsp, 40
    mov     rcx, message
    call    printf
    add     rsp, 40
    ret
message:
    db  'Hello, World', 0

Is what I currently have.

In addition to your code, these were quite helpful to understand a bit better:
https://msdn.microsoft.com/en-us/library/zthk2dkh.aspx
https://msdn.microsoft.com/en-us/library/9z1stfyw.aspx

Regarding 'making up my mind', no, I'm just learning, hence I was just trying some simple examples and trying to establish a baseline. Good thing too, it seems it turned out the 'baseline' was much more involved than I had expected.

I seem to have 'conquered' the 64 bit example, now to try for 32 bit variants, proper makefiles, etc. :)

Thanks for your help!

Offline dreamCoder

  • Full Member
  • **
  • Posts: 106
Re: Help with Hello World and NASM on mingw64
« Reply #6 on: November 26, 2018, 01:10:40 PM »
Glad you sorted it out.

But be careful with what you read from MSDN. Some things don't quite apply to C when it comes to parameter-passing. For example, printf don't take in XMM arguments. So when it comes to C, I don't usually direct people to MS links and articles because they tend to mislead. Here, try this

format: db '%f',0
myFloat: dq 56.4067

movq xmm1,[myFloat]   ;according to "parameter-passing", myFloat should go here... but...
;mov rdx,[myFloat]
mov rcx,format
call printf

Good luck with your "64-bit conquest"  ;D 

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2373
  • Country: us
Re: Help with Hello World and NASM on mingw64
« Reply #7 on: November 26, 2018, 08:12:24 PM »
Unless I'm mistaken (quite possible!) printf wants the count of float parameters in al.

Best,
Frank


Offline dreamCoder

  • Full Member
  • **
  • Posts: 106
Re: Help with Hello World and NASM on mingw64
« Reply #8 on: November 26, 2018, 08:42:31 PM »
Not on Win64 frank. For Linux64, yes. Things deviate sharply for C on both platforms.


Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2373
  • Country: us
Re: Help with Hello World and NASM on mingw64
« Reply #9 on: November 26, 2018, 09:15:08 PM »
Okay, my mistake. Thanks dreamCoder!

Best,
Frank