NASM - The Netwide Assembler
NASM Forum => Using NASM => Topic started by: Zulfi Khan on June 25, 2009, 01:55:34 PM
-
Hi,
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
_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
D:\NASMPR~1>
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 [nul.map]:
Libraries [.lib]:
Definitions File [nul.def]:
nasm1.o : fatal error L1101: invalid object module
Object file offset: 1 Record type: 7f
D:\NASMPR~1>
Can somebody plz help me with this. Guide me with a proper linker.
I am working on windows XP.
Zulfi.
-
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
..start:
; 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:
C:>HelloWorld.exe
Hello, World!
Hello, World!
Hope that helps you,
have fun,
Martin
-
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 - http://alink.sf.net (http://alink.sf.net)
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!
Best,
Frank
-
My apologies to the merely cheerful GNU mailman. Your message to the nasm-users list *did* go through - I just missed it...
Best,
Frank