I had an old game... Starflight. I think it came out in '86. Good ol' IBM PC jr days. I figured I'd break out a disassembler and see how it worked. I can see in the little that I've decoded, code size was optimized for sure... but I ended up jumping to an address that is outside of the file. That makes no sense.
I added the comments in below listing; they're my "thoughts".
Until other files are loaded with, I assume, int 0x3d
or int 0x0f
... since all segment registers point to the same memory segment.... and that segment is the code segment, the .COM file, every memory reference or jump should stay within the file. Yes?
Starflt.com
00000000 FA CLI ;Prevent interrupts
00000001 8CC8 MOV AX,CS ;Copy code segment to all segments
00000003 8ED0 MOV SS,AX
00000005 8EC0 MOV ES,AX
00000007 8ED8 MOV DS,AX
00000009 BE2901 MOV SI,word 0x0129 ;SI = 0x0129
0000000C 8B7C02 MOV DI,word [SI+0x02] ;DI = 0x3c15 (SI+2)
0000000F 47 INC DI
00000010 47 INC DI ;DI = 0x3c17
00000011 BB0507 MOV BX,word 0x0705 ;BX = 0x0705
00000014 8B1F MOV BX,word [BX] ;BX = 0xa924
00000016 81C30001 ADD BX,word 0x0100 ;BX = 0xaa24
0000001A 8BE3 MOV SP,BX ;SP = 0xaa24 (0x0e41)
0000001C 81C38000 ADD BX,word 0x0080 ;BX = 0xaaa4
00000020 8BEB MOV BP,BX ;BP = 0xaaa4 (0x0bae)
00000022 FB STI ;Restore Interrupts
00000023 FC CLD ;Clear direction flag
00000024 AD LODSW ;AX = DS:SI = 0xfa13
00000025 8BD8 MOV BX,AX ;BX = 0xfa13
00000027 FF27 JMP word [BX] ;Past COM EOF (0xd3a7)
Memory:
00000705 24 byte 0x24 '$'
00000706 A9 byte 0xA9 '©'
00000129 13 byte 0x13
0000012A FA byte 0xFA 'ú'
0000012B 15 byte 0x15
0000012C 3C byte 0x3C '<'
0000AA24 41 byte 0x41 'A'
0000AA25 0E byte 0x0E
0000AAA4 AE byte 0xAE '®'
0000AAA5 0B byte 0x0B
The program you are disassembling is a DOS COM program. You generally have the right idea but your memory offsets aren't correct. A DOS COM program is loaded into memory starting at a free segment in memory at offset 0x100 within that segment. The first 0x100 bytes are the DOS Program Segment Prefix (PSP). You are disassembling from offset 0x0000 and as a consequence are using the wrong memory addresses in an attempt to decode the COM program.
It is unclear what disassembler you are using, If you were to use ndisasm
you can change the origin point using the -o
option. If you aren't actually using ndisasm
you will have to tell the disassembler you are using that you want an origin point of 0x0100 instead of 0x0000. In the case of ndisasm
you can use:
ndisasm -o 0x100 -b16 Starflt.com
I found a copy of Starflight online and it appears to be similar code to yours. The output I get using -o 0x100
is:
00000100 FA cli 00000101 8CC8 mov ax,cs 00000103 8ED0 mov ss,ax 00000105 8EC0 mov es,ax 00000107 8ED8 mov ds,ax 00000109 BE2901 mov si,0x129 ; si = 0x129 0000010C 8B7C02 mov di,[si+0x2] ; di = 0x078a 0000010F 47 inc di 00000110 47 inc di ; di = 0x078c 00000111 BB0507 mov bx,0x705 00000114 8B1F mov bx,[bx] ; bx = 0xd4b6 00000116 81C30001 add bx,0x100 ; bx = 0xd5b6 0000011A 8BE3 mov sp,bx ; sp = 0xd5b6 0000011C 81C38000 add bx,0x80 ; bx = 0xd636 00000120 8BEB mov bp,bx ; bp = 0xd636 00000122 FB sti 00000123 FC cld 00000124 AD lodsw ; ds:si = ds:0x129 . ax = 0x0937 ; si=si+2, si=0x12B 00000125 8BD8 mov bx,ax ; bx = 0x0937 00000127 FF27 jmp [bx] ; jmp to cs:0x224c 00000129 37 aaa 0000012A 098A0700 or [bp+si+0x7],cx [snip] 00000704 F7B6D4E6 div word [bp-0x192c] [snip] 00000937 4C dec sp 00000938 22DB and bl,bl [snip] 0000224C 43 inc bx ; Execution will continue here 0000224D 43 inc bx 0000224E 4D dec bp 0000224F 4D dec bp 00002250 897600 mov [bp+0x0],si 00002253 8BF3 mov si,bx 00002255 AD lodsw 00002256 8BD8 mov bx,ax 00002258 FF27 jmp [bx]
As you can see the jmp [bx]
ultimately starts executing at cs:0x224c which happens to be in memory for this program.
I'd recommend getting ahold of Turbo Debugger and use a DOS emulator like DOSBox if you wish to step through old 16-bit real mode code like this. Starflight will run in DOSBox.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With