Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Linking assembly with ld in Windows [duplicate]

I am starting to learn x86 assembly on Windows. I am learning 32 bit x86 assembly. I use nasm and ld in order to compile my programs. I use a mingw32-make makefile as my build system. I am assuming ld came included with MinGW, but I am not sure of that. All I know is that it was already on my computer.

I wanted to compile a very simple program just to make sure everything was working and of course, it wasn't. When running my executable, a giant blue box came up and said 'This app cant run on your pc' and after closing the notification, the words Access is denied printed out onto my terminal.

This is my program:

global _main

_main:
  mov eax, 1
  ret

And this is my makefile:

main: learn.asm
    nasm -f win32 learn.asm -o learn.o
    ld learn.o -o learn.exe

Could someone help me fix this?

like image 842
Serket Avatar asked Nov 14 '22 22:11

Serket


1 Answers

Originally your question asked about using _start as an entry point. The way you were linking didn't include the C runtime.

With some versions of Windows you may get the error This app cant run on your pc when linking with MinGW LD if there is no .rdata (read only data) section under some circumstances. One circumstance appears to be an executable with an .idata section (import directory) not referenced by the header and doesn't contain an .rdata section. This appears to be the case when the MinGW LD linker creates the executable from your code when not using a C runtime. To fix the problem add an .rdata section with at least one byte of data. This should work:

global _start

section .rdata
db 0

section .text
_start:
    mov eax, 1
    ret 

You also need to place your code in the .text section or you may encounter other problems. You can then assemble and link with:

nasm -fwin32 learn.asm -o learn.obj
ld -o learn.obj -o learn.exe

If you want to use _main and intend to use the C runtime then you don't need to create an .rdata section, however you would assemble and link with:

nasm -fwin32 learn.asm -o learn.obj
gcc -m32 learn.obj -o learn.exe

My Recommendation for Linking

Alternatively you can use a different linker than LD. GoLink in particular should generate an executable from the code you were using. You can create a Win32 console application with a _start entry point this way:

nasm -fwin32 learn.asm -o learn.obj
golink /console /entry _start learn.obj

GoLink will produce an executable with proper headers and sections that Windows should have no problem running without the need to add an .rdata section.

If you have MSVC/C++ installed you can also use the Microsoft linker:

nasm -fwin32 learn.asm -o learn.obj
link learn.obj /entry:start /subsystem:console
like image 171
Michael Petch Avatar answered Dec 09 '22 12:12

Michael Petch