Page 1 of 1

custom output format

Posted: Sat May 07, 2011 10:53 am
by mariuszp
I am using a custom executable format for my operating system. My problem is that I can't find a way to write a 'driver' or something for nasm to create executables in that format. I mean, there is a way to add those 'drivers/extensions' to nasm, right?

Does anyone know of a good tutorial/manual about nasm output format drivers, or at least a good documentation of the RDOFF format so I can convert it?

P.S. if this information is neccessary: my format has just relocation tables and external references - no section support.

Re: custom output format

Posted: Sat May 07, 2011 10:25 pm
by Brendan
Hi,
mariuszp wrote:I am using a custom executable format for my operating system. My problem is that I can't find a way to write a 'driver' or something for nasm to create executables in that format. I mean, there is a way to add those 'drivers/extensions' to nasm, right?
There's 3 ways:
  • Modify the NASM source code so that NASM can generate your custom format
  • Write a conversion utility to convert from an existing format to your format (a limited type of linker)
  • Implement your custom format on top of an existing format (e.g. flat binary) using macros
I use "flat binary" and macros to generate my own executable file format (and also do the same to generate bootable ISO9660 disk images). You'd be surprised how much the NASM preprocessor, etc can handle. For an example, here's a specification that describes my executable file format, and here's the include file that handles it all.


Cheers,

Brendan

Re: custom output format

Posted: Thu Sep 20, 2012 7:14 pm
by Unsigned
Brendan wrote: There's 3 ways:
  • Modify the NASM source code so that NASM can generate your custom format
  • Write a conversion utility to convert from an existing format to your format (a limited type of linker)
  • Implement your custom format on top of an existing format (e.g. flat binary) using macros
Please, can you tell me how to implement my own format using macros or something? I've tried in two ways, but both failed.
The first thing i tried failed because nasm doesn't allow several org directives, although i need that.
The second thing failed because nasm doesn't allow sections wich overlap, and i need that too (nasm seems not to know i'm going to put them in DIFFERENT segments!).

What i want to do is to write a binary file wich contains a code segment and a data segment, and both segments must start at offset 0.
An example (doesnt work):

cpu 386
bits 32
db 'PROG' ; file type: program
dd CODE_END-CODE_START ; code size
dd DATA_END-DATA_START ; data size
dd 0 ; uninitialized data size
dd 1024 ; stack size
org 0 ; this should work, but doesn't
CODE_START:
instructions go here
CODE_END:
org 0 ; this should work, but doesn't
DATA_START:
data goes here
DATA_END:

Now, both CODE_START and DATA_START should be 0, but they are counted from the start of the file despite i want them to be counted from what i put in the org directive. Any ideas about how i should do this? Thanks in advance.

Re: custom output format

Posted: Thu Sep 20, 2012 9:51 pm
by Love4Boobies
Unsigned wrote:Please, can you tell me how to implement my own format using macros or something? I've tried in two ways, but both failed.
You should use macros because they make your job less error-prone. But in the end, all your headers and data structures will be a bunch of DB's, DW's, etc.
Unsigned wrote:The first thing i tried failed because nasm doesn't allow several org directives, although i need that.
The second thing failed because nasm doesn't allow sections wich overlap, and i need that too (nasm seems not to know i'm going to put them in DIFFERENT segments!).
Sounds like what you really want is either one section or multiple, non-overlapping sections.
Unsigned wrote:What i want to do is to write a binary file wich contains a code segment and a data segment, and both segments must start at offset 0.
An example (doesnt work):

...

Now, both CODE_START and DATA_START should be 0, but they are counted from the start of the file despite i want them to be counted from what i put in the org directive. Any ideas about how i should do this? Thanks in advance.
If you want them in the same segment, they can't both have the same origin (so just delete the second origin). If you want them in different segments, then use one section for each.

Re: custom output format

Posted: Thu Sep 20, 2012 10:26 pm
by Unsigned
Love4Boobies wrote:If you want them in different segments, then use one section for each.
It doesn't work. :(
This is my actual code:

Code: Select all

cpu 386
bits 32
STKS equ 1024
section HEADER
db 'KRNL'          ; file type: operating system kernel
dw 0x0001          ; file type version: currently 0.1
dd 0               ; unique identification number, used to know where it booted from
dd CODEND-CODSTART ; code size
dd DATEND-DATSTART ; data size
dd 0               ; uninitialized data size
dd STKS            ; stack size
section CODE
CODSTART:
mov ax,32
mov fs,ax
mov word[fs:0xb8000],0x0f41
stoploop:
jmp stoploop
CODEND:
section DATA
DATSTART:
dd CODSTART
dd DATSTART
DATEND:
The last two words in the file should be 0, but when opening it with a hexadecimal editor, i see they are 28 and 48. I think nasm is assuming that these sections will go in the same segment, so it doesn't set their origins to 0. I need these 3 sections to appear in this order in the file, and the code must have an origin of 0, and the data must have an origin of STKS.

Re: custom output format

Posted: Thu Sep 20, 2012 10:55 pm
by Brendan
Hi,
Unsigned wrote:What i want to do is to write a binary file wich contains a code segment and a data segment, and both segments must start at offset 0.
An example (doesnt work):
ORG doesn't work like that in NASM, and you shouldn't be using ORG at all. What you do want to do is define sections. For an example:

Code: Select all

     SECTION .sector1 progbits start=0x0000 vstart=0x1000
     SECTION .sector2 progbits start=0x0200 vstart=0x1200
     SECTION .sector3 progbits start=0x0400 vstart=0x1400
     SECTION .text progbits follows=.sector3 vfollows=.sector3
     SECTION .data progbits follows=.text vfollows=.text
     SECTION .common progbits follows=.data vfollows=.data
Notice that each section has 2 different start addresses (determined by "start" or "follows", and "vstart" or "vfollows"). The first says where the section begins in the resulting output file, and the second says where the section begins in virtual memory. Obviously, different sections can not overlap in the output file. However, different sections can overlap in virtual memory.

What you want might look something like this:

Code: Select all

;Define sections

     SECTION .header progbits start=0x00000000 vstart=0x00000000
     SECTION .text progbits follows=.header vstart=0x00000000
     SECTION .data progbits follows=.text vstart=0x00000000
     SECTION .bss nobits follows=.data vfollows=.data
     SECTION .stack nobits follows=.bss vfollows=.bss

;Set section start labels

     section .text
CODE_START:
     section .data
DATA_START:
     section .bss
BSS_START:
     section .stack
STACK_START:

;Header

     section .header
     db 'PROG' ; file type: program
     dd CODE_END-CODE_START ; code size
     dd DATA_END-DATA_START ; data size
     dd BSS_END-BSS_START ; uninitialized data size
     dd STACK_END-STACK_START ; stack size

     cpu 386
     bits 32

;Code and data goes here (can be in random order, just use "section whatever" where needed)

     section .text
     mov eax,[foo]
.l1: hlt
     jmp .l1

     section .data
foo: dd bar

     section .bss
bar: resd 1


;Set section end labels

     section .text
     align 4
CODE_END:

     section .data
     align 4
DATA_END:

     section .bss
     alignb 4
BSS_END:

     section .stack
     alignb 4
STACK_END:
Once you've got this working how you want, you can implement the entire thing as macros. In that case an executable's source code might look like this:

Code: Select all

     %include "exe_file_format_macro.inc"

     EXE_START 1234           ;Create header ("1234" is stack size)

     section .text
     mov eax,[foo]
.l1: hlt
     jmp .l1

     section .data
foo: dd bar

     section .bss
bar: resd 1

     EXE_END                   ;Macro to set the end labels

Cheers,

Brendan

Re: custom output format

Posted: Thu Sep 20, 2012 11:23 pm
by Unsigned
YAY!! Thank you very much, Brendan. It works. :D
I didn't try that before because i didn't find it in the nasm documentation.