Author Topic: Linux DOS  (Read 22997 times)

nobody

  • Guest
Linux DOS
« on: February 22, 2008, 07:21:20 PM »
I was playing around with some code to work under Linux AND DOS originally written in FASM. FASM seemed to want to dictate using 32bit jumps even for the 16bit code so I tried porting it to NASM 2.01 to see how it would compile. NASM did the job 'as wanted' and surprisingly without too many changes :) Changing a few '=' to equates and not being able to use '@@' as a reusable label was about it. Nice one NASM.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;Example of program that runs under  ;;
;;Linux and DOS (sort of)             ;;
;;Note :- as AX is not guaranteed to  ;;
;;be 0 on entry of .com   executable  ;;
;;AFAIK, use at own risk.             ;;
;;19/01/2008                          ;;
;;Adapted for NASM V2.01              ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

use16
     org    08048000h              ;Seems to be the norm for ELF ?
ComOff equ $$-100h                 ;Org 100h displacement
;----------------------------------------------------------
ehdr:                              ;Elf header
     db     0x7F, 'ELF'            ;Elf ident, might jump to Com if flag is ok (7F=JG)
     db     1                      ;32 bit architecture
     db     1                      ;little Endian
     db     1                      ;ELF version
Pad9:                              ;Start of padding, 9 bytes
     db     1                      ;Padding, 9 bytes. Keep it as add [bx+di],ax
                                   ;rather than adding [bx+si] if 0
                                   ;the less that is changed,
                                   ;the less to go wrong, perhaps...
     inc    sp                     ;Undo what was done by 7fELF111, don't worry about SI
     sub    [bx+di],ax             ;ax seems to be 0 on entry but, just in case
     sub    [bx+di],ax             ;if we got this far we should be ok
     jmp    Com
     times 9-($-Pad9) db 0         ;Rest of the padding, if any!
     dw     2                      ;Executable
     dw     3                      ;Intel 386+
     dd     1                      ;Version
     dd     start                  ;Program start
     dd     phdr - $$              ;Program header offset
     dd     0                      ;Section header offset
     dd     0                      ;Flags
     dw     ehdrsize               ;Elf header size
     dw     phdrsize               ;Program header size
     dw     1                      ;Number of program header entries
     dw     0                      ;Section header size
     dw     0                      ;Number of section header entries
     dw     0                      ;String table (undefined)
ehdrsize equ $-ehdr
;----------------------------------------------------------
     times  71-ehdrsize  db 0      ;Could use this wasted space for something...
Com:                               ;Where '7fE' JG +47h jumps too
     mov    eax,'DOS'+0d000000h    ;Change 'Linux',0ah to 'DOS',0dh,0ah
     mov    bx, 0ah                ;
     mov    [OrNot-ComOff],eax     ;
     mov    [OrNot+4-ComOff],bx    ;Messy offsets !
     mov    si,msg-ComOff
     call   dword OutputIt         ;Print message
     mov    ax,4c00h               ;Exit
     int    21h
     int    20h                    ;Just in case
;----------------------------------------------------------
align 16                           ;Keep Linux happy :)
phdr:                              ;Elf program header
     dd     1                      ;Load segment
     dd     0                      ;offset
     dd     $$                     ;Virtual address
     dd     $$                     ;Physical address
     dd     filesize               ;File image size
     dd     filesize               ;Memory image size
     dd     5                      ;Executable / readable x_r
     dd     1000h                  ;Alignment
phdrsize equ $-phdr
;----------------------------------------------------------
use32
start:
     mov    eax,4                  ;Write msg to console
     mov    ebx,1                  ;
     mov    ecx,msg                ;
     mov    edx,msg_size           ;
     int    80h                    ;

mov    eax,1                  ;Exit
     xor    ebx,ebx                ;
     int    80h                    ;
;----------------------------------------------------------
msg  db     'This program has been run from some sort of '
OrNot:
     db     'Linux',0ah
msg_size equ $-msg
;----------------------------------------------------------
use16
OutputIt:                          ;Print text string from si
     mov    ah,0eh                 ;could use int 21h and ah=2 instead with dl
     mov    bx,05h                 ;probably don't need this (graphics mode color)
@1:  lodsb
     or     al,al
     jz     @2                     ;End of string
     int    10h
     jmp    @1
@2:  ret

filesize equ $-$$

nobody

  • Guest
Re: Linux DOS
« Reply #1 on: February 22, 2008, 07:33:39 PM »
Wow, that didn't look so good so I've posted the code on
http://pastebin.com/f344dcdc
to try and make it a little clearer. To compile save as 'whatever.asm' then 'nasm whatever.asm -o whatever.com'(or maybe even .exe)

nobody

  • Guest
Re: Linux DOS
« Reply #2 on: February 24, 2008, 01:25:30 AM »
> FASM seemed to want to dictate using 32bit jumps even for the 16bit code

NO.

nobody

  • Guest
Re: Linux DOS
« Reply #3 on: February 24, 2008, 07:13:25 AM »
Yes, *in this particular case*. Do not get the idea that this is the case for all 16bit code. For instance...

Org 08048000h
use16
jmp short @1
@1:

FASM "error: value out of range.", at least with Ver 1.67.11 - 1.67.26.
NASM OK "EB 00" Ver 2.01

If we change the code to:-

Org 08048000h
use16
jmp short dword @1
@1:

FASM OK "66 EB 00"
NASM "error: mismatch in operand sizes"

What I have done is a little unconventional with mixing the 16bit and 32bit code and since there are ways to generate what I want using FASM and not what FASM thinks I want, I can live with that.