Author Topic: Linking prob  (Read 3124 times)

Zulfi Khan

  • Guest
Linking prob
« on: June 25, 2009, 01:55:34 PM »
I have compiled a simple program using nasm.

section .data
   hello:     db 'Hello world!',10    ; 'Hello world!' plus a linefeed character
   helloLen:  equ $-hello             ; Length of the 'Hello world!' string
                                      ; (I'll explain soon)

section .text
   global _start

   mov eax,4            ; The system call for write (sys_write)
   mov ebx,1            ; File descriptor 1 - standard output
   mov ecx,hello        ; Put the offset of hello in ecx
   mov edx,helloLen     ; helloLen is a constant, so we don't need to say
                        ;  mov edx,[helloLen] to get it's actual value
   int 80h              ; Call the kernel

mov eax,1            ; The system call for exit (sys_exit)
   mov ebx,0            ; Exit with return code of 0 (no error)
   int 80h

It went fine.D:\NASMPR~1>nasm -f elf nasm1.asm


But when I am trying to link I am getting error.

D:\NASMPR~1>Link nasm1.o

Microsoft (R) Segmented Executable Linker  Version 5.60.339 Dec  5 1994
Copyright (C) Microsoft Corp 1984-1993.  All rights reserved.

Run File [nasm1.exe]:
List File []:
Libraries [.lib]:
Definitions File [nul.def]:
nasm1.o : fatal error L1101: invalid object module
Object file offset: 1 Record type: 7f


Can somebody plz help me with this. Guide me with a proper linker.

I am working on windows XP.


mene mene tekel

  • Guest
Re: Linking prob
« Reply #1 on: June 25, 2009, 09:08:42 PM »
Hi Zulfi,

this will never work because you are mixing up almost everything.
First, you are workung on Windows XP 32bit, so you have to compile a win32 .obj being able to link it, not a linux/unix .o library on elf base.
Within you code you are using bios interrupt calls being blocked completely by the XP operation system (except you write a driver.. other stuff) - you have to use the win32 API. One option here would be the WriteConsoleA (ASCII, not UNICODE!) from kernel32.dll or even the C/C++ print() of crtdll.dll. In the later its up to you to balance the stack.

Example code:

; ---------------------------------------------------------------------------
; ---                        H E L L O   W O R L D                        ---
; ---------------------------------------------------------------------------

; --------- Compiler directives
            bits  32                            ;32bit code
            cpu   586                           ;Pentium instruction set

; --------- Import
import      GetStdHandle      kernel32.dll
import      WriteConsoleA     kernel32.dll
import      printf            crtdll.dll

; --------- Extern
extern      GetStdHandle
extern      WriteConsoleA
extern      printf

segment .rdata rdata public use32 align=1 class=DATA
pString     db    'Hello, World!', 0x0a, 0x0d, 0x00
uString     equ   $-pString

segment .bss   data  public use32 align=1 class=DATA
rString     resd  1

segment .code  code  public use32 align=1 class=CODE
            ; Print pString
            push  dword pString
            call  [printf]
            add   esp,  byte  4*1

; Write pString
            push  0x00000000   ;Reserved NULL
            push  dword rString
            push  dword uString
            push  dword pString
            push  dword -11    ;OUTPUT HANDLE
            call  [GetStdHandle]
            push  eax
            call  [WriteConsoleA]

; Set return value
            mov   eax,  0        ;OR use the exit(0) call

ret   4*3
; ---------------------------------------------------------------------------

You will compile and link that:
nasm -fobj HelloWorld.asm
alink -oPE -subsys con HelloWorld.obj

And you will receive HelloWorld.exe as an excecutable PE file.

Running that will result in the console output:
Hello, World!
Hello, World!

Hope that helps you,
have fun,

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2446
  • Country: us
Re: Linking prob
« Reply #2 on: June 26, 2009, 03:44:09 AM »
Hi Zulfi,

As Martin says, you've got a bit of a "mismatch" there. Nasm will produce several "linkable object" formats. "-f elf" asks for an "Executable Linkable Format" (ELF). The first thing in a ELF object is 7f, 'E', 'L', 'F' - since your error mentions 7f, it doesn't look like it got far. :)

Your linker is expecting an "OMF" (Object Module Format) object, obtained by Nasm's "-f obj" switch.

The code Martin showed you might just work with that linker - try it. If not, you can get Alink here -

What you've got there isn't actually a "bios interrupt", but a "Linux interrupt" - "the" Linux interrupt, in fact. Won't work in Windows, and bios interrupts won't work in Linux (without jumping through hoops I haven't figured out yet). The code, the output format, the linker, and the OS all need to match. This is the primary purpose of a "hello world" program - to get the tools working together. It gets easier after that.

Unless I'm mistaken, WinXP still has a "fake dos" subsystem with it. This will allow you to use bios interrupts, and experiment with segmented memory models. If your intention is to learn to write a bootsector, this might be something you want to do. (bonus: Nasm can do .com files without any linker at all!) If the bootsector was a "false trail", you're probably better off to learn Windows programming.

Speaking of "the bootsector", I tried to approve your message to the nasm-users list, but haven't seen it posted. Either I screwed up, or that "drunken GNU" mailman screwed up. Neither of us are infaillable! Could you re-post? Or maybe this is a better place to communicate...

Nice example, Martin. Thanks!


Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2446
  • Country: us
Re: Linking prob
« Reply #3 on: June 26, 2009, 03:52:38 AM »
My apologies to the merely cheerful GNU mailman. Your message to the nasm-users list *did* go through - I just missed it...