Sign in to follow this  
andrew1123

how to create EXEs with NASM...

Recommended Posts

...Anyone know how? I use this to get a COM file: "nasmw -f bin whatever.asm -o whatever.com" (I don't know why it came as 'nasmw.exe' and not 'nasm.exe.' I could always change it to 'nasm.exe' if I wanted) ...So, how do I create an EXE out of the COM file? Or, if I can, how do I create an EXE using "-f" in the nasmw command line? (Or any other way to make an EXE with NASM code) Thanks. :)

Share this post


Link to post
Share on other sites
It is platform specfic, but assuming Windows:

nasmw input.asm -f win32 -o output.exe

If you do nasmw -h to print the help, it gives instructions on how to obtain a list of the valid format arguments which may be used.

You could create an EXE directly from the COM file, but it'd require manually writing the PE header -- which would be a reasonably pointless exercise.

Share this post


Link to post
Share on other sites
Quote:
Original post by andrew1123
But how do I create a standalone EXE, not running on top of any other OS? An OS itself, basically.


That's an answer which could fill a book (literally) and so I will simply direct you to OSDev.org - it hosts wikis (one of which was moved from Mega-Tokyo) which detail a number of things -- including the setup of a cross compiler toolchain -- involved in the development process. It's not too hard, although it's not quite absolutely trivial.

Sorry I can't give a better response -- but even the process of setting up the development environment is quite a lengthy description, never mind the design decisions in creating an operating system (or even, to an extent, any freestanding program) itself.

Share this post


Link to post
Share on other sites
I second OSDev.org

OSs are not a single *.exe. An OS is just an envirement made up of many programs, ranging from pure binary, to ELF,EXE, etc file formats.

For example, the bootloader will be a pure binary program, which will load
and execute either a second stage loader, or a main kernel program. This
program could be ELF, or even an EXE.

btw, using a cross compilier is not required (Its recommended, although
I could never get it to work). I use DJGPP/NASM/binutils/LD-elf instead ;)

There is alot involved, as previously posted. Good luck!

Share this post


Link to post
Share on other sites
Quote:
Original post by Crypter
I second OSDev.org

OSs are not a single *.exe. An OS is just an envirement made up of many programs, ranging from pure binary, to ELF,EXE, etc file formats.

For example, the bootloader will be a pure binary program, which will load
and execute either a second stage loader, or a main kernel program. This
program could be ELF, or even an EXE.

btw, using a cross compilier is not required (Its recommended, although
I could never get it to work). I use DJGPP/NASM/binutils/LD-elf instead ;)

There is alot involved, as previously posted. Good luck!


All I meant by OS is that it doesn't run on top of another OS. So, saving it as binary, that's standalone, right? It doesn't NEED MS-DOS, right? Any x86 PC, right?

Share this post


Link to post
Share on other sites
Every program you write and use runs on top of the OS. Any file on your computer with an .exe extension is likely in portable executable format and is interpreted by and run by the windows operating system.

The bin output option for nasm just dumps the straight binary bits of the machine code to a file, rather than provided them with any particular header like elf or pe. It may be the case that windows can run such files - I think it interprets them as old ms-dos com files but I'm not sure.

In any case I'm not sure what you mean by an "exe" and not running on top of the OS. Any file with an .exe extension is almost certainly a windows executable and requires windows to run.

Actually running a program in the absence of an OS is very difficult and requires starting in 16-bit assembly. You have access to no system calls, no drivers, no memory management, etc.

You should be more specific about what you are trying to do

Share this post


Link to post
Share on other sites
What I'm trying to do is write a program in NASM that doesn't need to run on top of say Windows. I didn't know that EXE was only in Windows. I thought it was the universal executable name. .COM is DOS executable, so can't that run without Windows? I'm not using any Window libraries, no drivers. here's an example of some NASM code

ORG 100h
MOV AH,09h
MOV DX,STRING
INT 21h
MOV AH,00h
INT 16h
STRING DB "Hello World!$"

That doesn't really NEED Windows, does it? Just the Processor (And maybe some other PC parts, too), right?

Share this post


Link to post
Share on other sites
Quote:

All I meant by OS is that it doesn't run on top of another OS. So, saving it as binary, that's standalone, right? It doesn't NEED MS-DOS, right? Any x86 PC, right?

That is correct -- kind of. Your program will not boot from it unless
you have a bootloader program.

Also, depending on resources use (and its a 32bit program), you will need
to set up the GDT and IDT tables, and jump into a 32bit mode (Such as pmode)

If you dont want it to work with an OS, you will still need to develope
these small details. (All of these are useually handled by the bootloader)

Using your code, you would also need to insure you load your program at
address 0100:0. And you will need to write your own INT 21h and INT 16h
routines, as your code will not work.

I would like to add INT 21h are DOS interrupts. As you are not using DOS,
INT 21h will be completely non existant. Sorry :(

Also, EXE is just a file format (The most common are MZ and PE formats)
It isnt Windows-only.

Share this post


Link to post
Share on other sites
OK. so are interrupts the only thing I can't use because of it being DOS?

Clearly I don't know what I'm talking about. I don't know how to make a bootloader, I'm checking OSdev now, and I have no clue how NOT to use interrupts using NASM only.

Share this post


Link to post
Share on other sites
To run software which is "operating system independent", at the minimum you will need to reboot the computer and run your code from a floppy disk. The floppy will need to have some elements of an operating system on it -- e.g. a boot loader to load your code from the floppy into RAM. But, then you will have a difficult time even writing to the video display :-)

[Edited by - AIDev on May 2, 2007 6:21:46 PM]

Share this post


Link to post
Share on other sites
Quote:
Original post by andrew1123
OK. so are interrupts the only thing I can't use because of it being DOS?


You can use *hardware interrupts*, but you can only use some of the *software interrupts* (i.e. not int 21h). What kind of program are you trying to write? If it involves a real program that people can interact with using an operating system, then your file will be OS-dependent. (Otherwise, it will be VERY difficult even to get mouse input or write in a high-resolution graphics mode.)

The very structure of the file which you produce -- e.g. EXE -- is operating system dependent. The COM file is probably the closest to being OS-independent as you can get, but it comes with unique limitations since it doesn't even assume the processor is running in protected mode (which means you'll only have access to 640K of RAM).

You hear about games or applications being able to be run in Linux, Windows, Mac OS, etc. This is done by actually writing some parts of the program very specifically for each platform, then generating a separate executable file for each platform. So, a single executable file is never made which can be run on every platform.

Share this post


Link to post
Share on other sites
Quote:

OK. so are interrupts the only thing I can't use because of it being DOS?

Yep. You can, however, use BIOS interrupts in 16bit real mode (ie, in the bootloader)

ie, this is from my OS bootloader (16bit code)

;*******************************************************
; Print null terminated string
; (DS:SI=>null terminated string)
;*******************************************************

Print:
lodsb
or al, al ; al=current character
jz PrintDone ; null terminator found
mov ah, 0eh ; get next character
int 10h
jmp Print
PrintDone:
ret



Under pmode, BIOS interrupts are not available, so you will need to access video
memory directly (Useually b800:0)--This is easy in C.

Hope this helps;

Share this post


Link to post
Share on other sites
Seriously what are you trying to do?

If you're just displaying text on the screen it's probably easier to just write the text directly to memory rather than going through the bios.

Share this post


Link to post
Share on other sites
Quote:
Original post by cshowe
Seriously what are you trying to do?

If you're just displaying text on the screen it's probably easier to just write the text directly to memory rather than going through the bios.


I'm learning how to create an OS. I have to use BIOS because I don't want it to run on top on any other OS.

Share this post


Link to post
Share on other sites
This will do what you want it to do:

Hello.asm

[BITS 16] ; 16bit real mode instructions

[ORG 07c00h] ; BIOS loads bootloader at 07c00:0

jmp main

;*******************************************************
; Print null terminated string
; (DS:SI=>null terminated string)
;*******************************************************

Print:
lodsb
or al, al ; al=current character
jz PrintDone ; null terminator found
mov ah, 0eh ; get next character
int 10h
jmp Print
PrintDone:
ret

;******************************************************
; Data section
;
;******************************************************

Msg db "Hello, World!", 0

main:

cli ; trap interrupts
xor ax, ax
mov ds, ax
mov ax, 09000h
mov ss, ax ; stack space between 09000h and 0FFFFh
mov sp, 0FFFFh

mov si, Msg ; print message
call Print

STOP:
hlt


%if ($-$$) > 512
% error "Bootloader must be less then 512 bytes"
%endif

times 510 - ($-$$) db 0 ; Insure bootloader is 512 bytes
dw 0AA55h ; some older BIOSs require boot sig



Assemble as:

nasm -f bin Hello.asm -o Hello.bin

Copy Hello.bin to the bootsector of a floppy disk (or use an emulator),
and it will display "Hello, World!" -- without requiring any OS.

This should get you started[smile]

Share this post


Link to post
Share on other sites
Quote:

thanks for the link! very helpful. though, someone said before that INT 16h isnt BIOS, but it is on here.

Actually, I dont see any IBM BIOS interrupts there.

Share this post


Link to post
Share on other sites
Ok, keep in mind that this is hard - really hard

you might look at

http://developer.intel.com/products/processor/manuals/index.htm

That's the complete set of manuals for the IA-32 architecture.

Of particular interest to OS development are volumes 3A and 3B which
will tell you how to set up all the descriptor tables (Interrupt, Local and Global), switch to protected mode (if your bootloader doesn't already), and use the memory management stuff.

Also if you're doing OS development you should download a good emulator. Bochs is what people tend to use but I've always found it a bit obnoxious to set up and use. Qemu is another option that I prefer.

Share this post


Link to post
Share on other sites
Quote:
Original post by Crypter
This will do what you want it to do:

Hello.asm
*** Source Snippet Removed ***

Assemble as:

nasm -f bin Hello.asm -o Hello.bin

Copy Hello.bin to the bootsector of a floppy disk (or use an emulator),
and it will display "Hello, World!" -- without requiring any OS.

This should get you started[smile]


THANK YOU!!! I've been wondering how the heck a bootloader is made!

Share this post


Link to post
Share on other sites
Quote:
Original post by Crypter
Quote:

thanks for the link! very helpful. though, someone said before that INT 16h isnt BIOS, but it is on here.

Actually, I dont see any IBM BIOS interrupts there.


go to 'categories' and click BIOS. theres lots

Share this post


Link to post
Share on other sites
Quote:

THANK YOU!!! I've been wondering how the heck a bootloader is made!

I should note that the code I posted isnt a "bootloader" in a sense,
it is "self booting". It is missing alot of details (ie, the actual
loading of the kernel ak, your EXE)

OSDev.org would be a great help here. Search for: GDT, pmode (Protected mode),
and kernel loading (EXE kernel).

I dont use EXE (I use ELF) so I cant help you with loading and executing EXEs.
OSDev.org is a great site[smile]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this