Statistics

Members: 1927
News: 293
Web Links: 1
Visitors: 4046665

Who's Online

We have 2 guests online
Damn Vulnerable LinuxDamn Vulnerable Linux (DVL) is a Linux-based (modified Damn Small Linux) tool for IT-Security & IT-Anti- Security and Attack & Defense. [CLICK HERE FOR MORE INFOS! ]

Featured Conference Video

T16-Recon2006-Joe_Stewart-OllyBonE.gif OllyBone - Semi-Automatic Unpacking on IA-32. View the conference video here!
Home
Writing a Boot Sector in A86
User Rating: / 2
PoorBest 
Written by Jan Verhoeven   


I have been coding for FreeDOS some time, but that is a C project and I rather hate C. It is so clumsy. That's also why I always code in A86 assembly language. The "No Red Tape" assembler that makes life a lot easier for programmers.

A86 is good. The debugger (D86) could be better, but not too much. I registered my version and I want to encourage everyone to follow my lead. The software is good enough to pay for it. And it ensures proper development of the software. If you can spare 20 bucks a month for the ISP, you should also spend this on quality software. During the last two years I have been submiutting bugs to Isaacson and all of them have been fixed in the latest version (4.03).

 

 

Besides A86 being the best assembler around, it has some idiosyncracies to which some people need to get used to. Plus my personal preferences, which might add to that...

  • When I refer to a memory location I use square brackets.
  • I use single quotes for texts
  • I use most of the A86 features.

Some of the A86 features are:

  • very powerful macro language
  • numbers starting with a ZERO are ALWAYS hex, no matter how they end
  • easy IF statements to reduce nonsense labelnames
  • local labels, like below: only two local labels.

I started out on the Z-8000, back in 1981, switched to the Z-80, Z-8, 8086, PIC 16Cxx, some 8051 (Barffff), some 68K (yummie yummie). Mainly in ASM and else in Modula-2. I have some really cool and useful routines lying around for DOS. And I'm gonna share them with the world.

The following code is a bootsector which can be used for noon-bootable disks. In this case for a 1.44 Mb floppy disk. You could use it to make a commercial out of every non-bootable disk.

First the code:

----- Code file ------------------------------------------------- name flopnb
title Floppy disk boot sector, non-bootable, 1.44 Mb page 80, 120

; version 1.0 : It works : OK 12-12-1998

lf       = 10
cr       = 13
org   0
jmp   short main       ; this is critical!
nop                    ; and this too!

; ----------------------

OEMname db 'StupiDOS'

BpS      dw    512              ; bytes per sector
SpA      db    1                ; sectors per allocation unit (=cluster)
ResSect  dw    1                ; reserved sectors, starting from sector 0
NrFats   db    2                ; number of FAT's on this disk
FiR      dw    224              ; number of entries in ROOT directory
Total    dw    2880             ; number of sectors per disk
ToM      db    0F0              ; Type of Media
SpF      dw    9                ; Sectors per Fat
SpT      dw    18               ; sectors per Track
Heads    dw    2                ; number of heads
Hidden   dw    0, 0             ; Hidden sectors
GrandTot dd    0                ; total for disks over 32 Mb
IntId    db    0, 0
BootSign db    029              ; extended boot signature
VolumeID dd    0566E614A        ; serial number ...
DiskLabl db    'DOS is MINE'    ; volume label
FATtype  db    'FAT-12  '       ; FAT type
db    'VeRsIoN=1.0', 0 ; for version control only

; ----------------------

L1:      push  si               ; stack up return address
ret                    ; and jump to it
print:   pop   si               ; this is the first character
mov   bx, 0            ; video page 0
L0:      lodsb                  ; get token
cmp   al, 0            ; end of string?
je    L1               ; if so, exit
mov   ah, 0E           ; else print it
int   010              ; via TTY mode
jmp   L0               ; until done

; ----------------------

main:    cld                    ; init direction flag
cli                    ; take care of 1 faulty batch of 88's in 1980
mov   ax, 07C0         ; this is the segmentvalue at start
mov   ds, ax           ; store it in DS, ES
mov   es, ax
mov   ax, 0            ; clear ax ...
mov   ss, ax           ; ... to prime the SS register
mov   sp, 07C00        ; set stackpointer
sti                    ; OK, interrupts may come again
call  print            ; show that message
db    cr
db    'This is not a bootable floppy. '
db    'Please strike any key to reboot.', cr, lf
db    'This floppy disk is formatted by FreeDOS', cr, lf, lf
db    'Please visit us at www.freedos.org', cr, lf, 0
L0:      mov   ah, 1            ; wait for keypress by ...
int   016              ; ...  interrogating keyboard
jz    L0               ; if no key pressed, loop back
mov   ax, 0            ; else address system variables
mov   es, ax           ; in order to ...
es mov   w [0472], 01234  ; signal: NO POST and go on ...
jmp   0FFFF:0000       ; with the next reboot
org   01FE             ; look for the dotted line and ...
db    055, 0AA         ; ... don't forget to sign!

------------------------------------------------- Code file -----

The first three lines are straightforward: name, title and page. Not much to tell about that. Then some version info for the programmer, some equates and the ORG statement.

If no ORG is supplied, A86 will assume it is ORG 0100. I ordered an ORG 0, which means several things:

  • start assembly at address 0
  • the output file will be called *.BIN

Bootsectors must start with some particular bytes. Therefore the first three bytes need to be either a short jump, a variable offset plus a NOP. Or a (long) jump without a NOP.

At offset 03 of the bootsector starts the DPB (Disk Parameter Block) which tells the OS what kind of disk this is. It starts off with an OEM name. Please put ASCII in there, or virus scanners might trip on it with a "Bloodhound warning".

After the description of the geometry of this disk, I included an extended boot signature, since we have ample room left. It contains Volume ID, Disk Label, and FAT-type strings.

The PRINT subroutine is a nice one. It will print the ASCIIZ string that follows it. This is quite a handy routine since you can simply change messages without having to worry about the address and length of the actual message.

Print is called like this:

        call   print
db     'Hello World', cr, lf, 0
...

Print takes the "return address" off the stack. This of course is no return address but the address of the message. What follows is easy:

  • get next character
  • IF (non-zero) print character ELSE leave loop ENDIF
  • the current si pointer is the actual return address... So we push it
  • and return to caller.

Perhaps a jmp si could be possible too, but I like clear code, in most cases. If you need obfuscated code, switch to C. :)

The actual program is very simple. It just sets up a stack and the segment registers, and then prints that it will do nothing. Gee, what a life...

After the message we wait for a key and next signal:

  • fast reboot
  • jump to the reboot vector

Whatever there will be between end of code and offset 01FE is not relevant (it could be your ad) but the last two bytes of the boot sector must be a valid boot signature.

That's it. With this code you can make your own custom non-bootsector.

I hope this software has also shown that linking and assuming are supported by A86, but certainly not necessary. Also, this software does not rely on any HLL calls. It's just assembly language as it should be.

I want to remark that this software is Open Source, according to the rules of the GNU GPL. Make sure you understand these rules before embedding this routine in your own software.