Author Topic: How to use ld.exe to link Hello World without using libraries/luser32?  (Read 33274 times)

Offline frankly

  • Jr. Member
  • *
  • Posts: 21
Hello and thank you in advance for any replies I get to this topic.

I really like how GoLink.exe uses user32.dll directly without any library requirements.
I have tested all the codes I posted here myself and they compile and link properly.

However, I would prefer to use NASM.exe and ld.exe to link this simple Hello World program if at all possible (again without using any libraries like luser32).

My ld.exe version is 2.12.90 (20020706)

I have tried changing my ld.exe command line and Hello1.asm code many different ways to link Hello1.obj to Hello1.exe with no success.

Working - Assembly Code (filename Hello1.asm) -

Code: [Select]

cpu 586
bits 32

EXTERN MessageBoxA

section .text

global START

START:
   push 0
   push dword caption
   push dword text1
   push 0
   call [MessageBoxA]

   ret

   caption db "Output Window",0
   text1 db "Howdy",0


Working - compile from Hello1.asm to Hello1.obj -
Code: [Select]
NASM.exe -f win32 Hello1.asm
(NASM.exe version 0.98.39)

Working - GoLink.exe compile from Hello1.obj to Hello1.exe -
Code: [Select]
GoLink.exe Hello1.obj user32.dll
(GoLink.exe version 0.2.5.4)

Please - If you are going to reply with code - please verify the code actually compiles and links to a working .exe file first.

Again, thank you in advance for any replies.

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: How to use ld.exe to link Hello World without using libraries/luser32?
« Reply #1 on: August 12, 2018, 11:31:00 PM »
Hi frankly,

Welcome to the Forum!

I don't do Windows, but I am fairly certain that what you want is not possible.

I note that you are using an extremely old version of Nasm. That probably isn't bothering you much.

Any Windows users have any advice on this?

Best,
Frank


Offline frankly

  • Jr. Member
  • *
  • Posts: 21
Re: How to use ld.exe to link Hello World without using libraries/luser32?
« Reply #2 on: August 13, 2018, 12:36:46 AM »
Thank you for welcoming me to the Forum, Frank.

Yes, I am tinkering around using an old Windows XP computer to do my experimental Assembly programming with for test purposes.

However, after compiling the Hello1.exe file in my original post, I have tested Hello1.exe on a Windows Vista Home Premium 32bit and a Windows 7 Home Premium 64bit and a Windows 7 Professional 64bit computer and it works smoothly on each one.

I have used ld.exe throughout the years and I have always been happy with it - and I am not that familiar with GoLink.exe and any unknown bugs it may have.  Maybe it's just wishful thinking but I really respect the people that wrote ld.exe and I am hoping they anticipated programmers wishing to access user32.dll, kernel32.dll, (etc) directly the same way that GoLink.exe does, without going through Libraries/luser32.

Offline frankly

  • Jr. Member
  • *
  • Posts: 21
Re: How to use ld.exe to link Hello World without using libraries/luser32?
« Reply #3 on: August 13, 2018, 02:16:45 AM »
I have attached the Hello1.exe file (1,536 Bytes) for anyone that wanted it.

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: How to use ld.exe to link Hello World without using libraries/luser32?
« Reply #4 on: August 18, 2018, 05:49:45 AM »
Hi frankly,
Perhaps I should clarify... What I meant to say was "not possible" is creating a 'doze executable without using the APIs. As you see from the "tinyest" thread, we don't need to use a linker at all. As you know, ld is open source, GoLink is not. I am uncertain what might be possible with ld. What is your objection to using a library?

Best.
Frank


Offline frankly

  • Jr. Member
  • *
  • Posts: 21
Re: How to use ld.exe to link Hello World without using libraries/luser32?
« Reply #5 on: August 18, 2018, 09:53:06 AM »
The objection I have is having to get updated/complete Libraries for each new version of an operating system and having to refer to those Libraries when linking to create the Portable Executable -

If the 'old way' to compiling a Portable Executable were -
Step 1 - Create your .asm file
Step 2 - Use NASM(version 0.98.39) to compile the .asm file into an .obj file
Step 3 - Find the correct Library for the Operating System you wish to run your Portable Executable on.
Step 4 - Verify that Library has the Functions within it in order to Link your Portable Executable.
Step 5 - Use ld.exe(version 2.12.90) to Link the .obj file using that Library to create the Portable Executable.

My 'new way' of compiling a Portable Executable eliminates Step 3 and Step 4 -
Step 1 - Create your .asm file
Step 2 - Use NASM(version 0.98.39) to compile the .asm file into an .obj file
Step 3 - Use GoLink.exe(version 0.2.5.4) to Link the .obj file to crete the Portable Executable.

I appreciate anything that makes my life easier.

Thank you very much again for allowing me to post my question on your Forum.

NASM.exe and ld.exe have always been my favorite compiler and linker.

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: How to use ld.exe to link Hello World without using libraries/luser32?
« Reply #6 on: August 18, 2018, 07:38:13 PM »
I was not aware that you needed different library versions for different Windows versions. Been a really long time since I last used Windows. Looking at the ld.exe documentation, they say that the ability to link directly  to a .dll without a library has not always been available. Possible that a newer version of ld.exe would help you?

Best.
Frank


Offline frankly

  • Jr. Member
  • *
  • Posts: 21
Re: How to use ld.exe to link Hello World without using libraries/luser32?
« Reply #7 on: August 18, 2018, 09:55:56 PM »
If what you are implying is true that would be Great!

I will have to look at the current versions of ld.exe(and nasm.exe) and see if I was 'missing the obvious' because I was using the older versions (when I get the time to do so).

Thank you Frank.

*IF* I find that ld.exe does allow direct linking using .dlls - I will post a reply here letting everyone know how to do it, step-by-step.

Offline frankly

  • Jr. Member
  • *
  • Posts: 21
Re: How to use ld.exe to link Hello World without using libraries/luser32?
« Reply #8 on: August 19, 2018, 10:39:51 PM »
I just got done modifying my Hello1.asm file and got it to compile to an .obj file that my old version of ld.exe can now link directly with user32.dll(and other dlls) without needing any assitance from libraries.

For those that missed my previous replies, I like to play around with Assembly Programming on my old WindowsXP(Service Pack 1)32bit computer using an old version of NASM.exe(0.98.39) and an old version of ld.exe(2.12.90 (20020706)) to see if the Portable Executables that they create can work on newer computers like my Windows 7 Home Premium(Service Pack 1)64bit computer.   And I found out tonight - They Do Work!

I had to make some adjustments to my Hello1.asm code to get it to work properly with ld.exe though (like using '_mainCRTStartup' for ld instead of GoLink's 'START' among other things...)

So here's my WORKING CODE that works under Windows XP Service Pack 1 32bit and under Windows 7 Home Premium Service Pack 1 64bit -

Hello2.asm -
Code: [Select]

cpu 586
bits 32

EXTERN _MessageBoxA

section .text

global _mainCRTStartup

_mainCRTStartup:
    push 0                  ; only the buttons 'OK'
    push dword caption      ; caption of the BOX
    push dword text1         ; text in the BOX
    push 0                  ; handle of the Box
    call _MessageBoxA      ; print BOX on screen

    ret

    caption db "OUTPUT WINDOW",0
    text1 db "Hello2!",0


Working compile from Hello2.asm to Hello2.obj -
Code: [Select]
NASM.exe -f win32 Hello2.asm
(NASM.exe version 0.98.39)

Working ld.exe compile from Hello2.obj to Hello2.exe -
Code: [Select]
ld.exe Hello2.obj C:\WINDOWS\system32\user32.dll -o C:\Hello2.exe
(ld.exe version 2.12.90 (20020706))

However there seems to be a few differences between using ld.exe and using GoLink.exe -
The resulting Hello2.exe file after the ld linking is a bloated 3535 Bytes compared to Hello1.exe size of 1536 bytes from GoLink.
Also the ld Hello2.exe throws up a Command Line window/shell along with the Output Window where the GoLink Hello1.exe only displays the Output Window.

I will look more into this when I can find the time to see if I can't find some ld.exe modifiers that will eliminate those extra bytes and not display the Command Line shell window.

I have included in Attachments the resulting Hello2.exe file for those interested in it.


Offline frankly

  • Jr. Member
  • *
  • Posts: 21
Re: How to use ld.exe to link Hello World without using libraries/luser32?
« Reply #9 on: August 19, 2018, 10:49:43 PM »
I began to think 'Why even bother with Libraries when the .dll already has the functions built into them?'

So I did a little research and found these two websites -

https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/4/html/Using_ld_the_GNU_Linker/win32.html
    ...Given the improvements in speed and memory usage, one might justifiably wonder why import libraries are used at all. There are two reasons -
    1. Until recently, the link-directly-to-dll functionality did not work with auto-imported data.
    2. Sometimes it is necessary to include pure static objects within the import library (which otherwise contains only bfd's for indirection symbols that point to the exports of a dll). Again, the import lib for the cygwin kernel makes use of this ability, and it is not possible to do this without an import lib...

https://sourceware.org/binutils/docs/ld/WIN32.html
    ...3. Symbol aliases can only be resolved using an import lib. This is critical when linking against OS-supplied dll’s (eg, the win32 API) in which symbols are usually exported as undecorated aliases of their stdcall-decorated assembly names.

    So, import libs are not going away. But the ability to replace true import libs with a simple symbolic link to (or a copy of) a dll, in most cases, is a useful addition to the suite of tools binutils makes available to the win32 developer. Given the massive improvements in memory requirements during linking, storage requirements, and linking speed, we expect that many developers will soon begin to use this feature whenever possible...


Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: How to use ld.exe to link Hello World without using libraries/luser32?
« Reply #10 on: August 20, 2018, 12:01:26 AM »
Thanks frankly! I'm sure our many speech-impaired Windows users thank you, too!

Best,
Frank


Offline sal55

  • Jr. Member
  • *
  • Posts: 18
Re: How to use ld.exe to link Hello World without using libraries/luser32?
« Reply #11 on: August 25, 2018, 12:50:50 AM »
I began to think 'Why even bother with Libraries when the .dll already has the functions built into them?'
....
    So, import libs are not going away. But the ability to replace true import libs with a simple symbolic link to (or a copy of) a dll, in most cases, is a useful addition to the suite of tools binutils makes available to the win32 developer. Given the massive improvements in memory requirements during linking, storage requirements, and linking speed, we expect that many developers will soon begin to use this feature whenever possible...

I don't use import libraries anymore, and for a few years have only linked with .dll files.

I've done this with ld, when used directly (I found some problems using ld via gcc), and also briefly used GoLink. But GoLink has some strange problems (for example, the handling of imported dll function names as data - for use as function pointers - is rather peculiar). While ld on Windows 10 seems to be unstable when used directly, but is OK via gcc (but which then doesn't like dll files...).

Now I use my own linker (actually, I have a product that is a combined assembler/linker, with multiple .asm [my syntax] as input, and .exe as output). And that relies on using dll files to use import libraries. It can't use external .a, .o. .obj or .lib files.

Any dll files and functions used find their way as imported libraries into the .exe file (there is no static linking).

At the moment this system seems to work fine. I'm not sure why linkers have always been perceived as  complicated programs (and I first used them in the 1970s), or why they need def and lib files, as the task they perform is straightforward.

Offline stressful

  • Full Member
  • **
  • Posts: 105
  • Country: 00
    • CPU2.0
Re: How to use ld.exe to link Hello World without using libraries/luser32?
« Reply #12 on: September 02, 2018, 05:38:22 PM »
@frankly, you're close

All you need is the correct path to "user32.dll" and "kernel32.dll" and use the correct emulation in your linking script. I modified your code a little bit;

Code: [Select]
;nasm -f win this.asm
;ld -m i386pe this.obj {path to user32.dll} {path to kernel32.dll} -o this.exe (for console)
;ld -m i386pe this.obj -subsystem windows {path to user32.dll} {path to kernel32.dll} -o this.exe (for Win32 subsystem)

bits 32
extern _MessageBoxA
extern _ExitProcess

section .text
global _start

_start:
   push 0
   push dword caption
   push dword text1
   push 0
   call _MessageBoxA

   push 0
   call _ExitProcess

   caption db "Output Window",0
   text1 db "Howdy",0

Hope that helps
« Last Edit: September 02, 2018, 06:58:25 PM by stressful »

Offline stressful

  • Full Member
  • **
  • Posts: 105
  • Country: 00
    • CPU2.0
Re: How to use ld.exe to link Hello World without using libraries/luser32?
« Reply #13 on: September 02, 2018, 05:49:33 PM »
Sorry, I thought it hadn't been resolved.

But if you literally meant "without importing libraries", then our dear friend "dreamcoder" probably has something for you. I think it's called "creeping" rather than "importing"  ;D

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

Offline frankly

  • Jr. Member
  • *
  • Posts: 21
Re: How to use ld.exe to link Hello World without using libraries/luser32?
« Reply #14 on: September 03, 2018, 12:54:31 AM »

@stressful

Dont be sorry - I APPRECIATE all the help anyone gives me.

I like the touchups you did on my Hello2.asm code.  I am sure using '_ExitProcess' instead of my simple 'ret' is the proper way to exit.

I look forward to using your ld command line (for win32 subsystem) when I have the time.

I never saw dreamcoder's thread before and I can not wait to play around with it (again, when I have the time).

I am SO GLAD there are others out there like me that appreciate NASM.

I look forward to seeing more replies from you in the future!

I hope to be posting soon on another thread I started on creating .dll files using NASM -
https://forum.nasm.us/index.php?topic=2458.0

Thank you again for your reply