Ok... On MS-DOS, COM files follows the TINY memory model, where CS=DS=ES. For EXE files any model can be used, so, there are no garantees about DS and ES and they must be initialized. SS is initialized by DOS to use its stack (the linker will warn you: "No stack", but DOS stack is used!). Here's two small programs to show you the registers on entry:
; SHOW.ASM
; This is a COM executable:
;
; nasm -f bin show.asm show.com
;
bits 16
%macro dword2hexstr 2
lea di,[%1]
mov eax,%2
call dw2hex
%endmacro
%macro word2hexstr 2
lea di,[%1]
mov ax,%2
call w2hex
%endmacro
org 0x100
; Save modified registers
mov [cs:oldESP],esp
mov [cs:oldDS],ds
push cs
pop ds
mov [oldEBX],ebx
mov [oldEDI],edi
; Prepare string
lea di,[_eax]
call dw2hex
dword2hexstr _ebx, [oldEBX]
dword2hexstr _ecx, ecx
dword2hexstr _edx, edx
dword2hexstr _esi, esi
dword2hexstr _edi, [oldEDI]
dword2hexstr _ebp, ebp
dword2hexstr _esp, [oldESP]
word2hexstr _cs, cs
word2hexstr _ds, [oldDS]
word2hexstr _es, es
word2hexstr _ss, ss
word2hexstr _fs, fs
word2hexstr _gs, gs
lea dx,[msg]
mov ah,9
int 0x21
mov ax,0x4c00
int 0x21
; Entry: DS:DI points to buffer,
; AL = hexvalue to convert
; Destroys: BX, DI (advances)
b2hex:
movzx bx,al
shr bx,4
mov bl,[bx+hextbl]
mov [di],bl
inc di
movzx bx,al
and bx,0x0f
mov bl,[bx+hextbl]
mov [di],bl
inc di
ret
w2hex:
xchg al,ah
call b2hex
xchg al,ah
call b2hex
ret
dw2hex:
push eax
shr eax,16
call w2hex
pop eax
call w2hex
ret
hextbl:
db `0123456789ABCDEF`
oldEBX: dd 0
oldEDI: dd 0
oldESP: dd 0
oldDS: dw 0
; EAX=00000000 EBX=00000000 ECX=00000000 EDX=00000000
; ESI=00000000 EDI=00000000 EBP=00000000 ESP=00000000
; CS=0000 DS=0000 ES=0000 FS=0000 GS=0000
msg: db `EAX=`
_eax: db `00000000`
db ` EBX=`
_ebx: db `00000000`
db ` ECX=`
_ecx: db `00000000`
db ` EDX=`
_edx: db `00000000\r\n`
db `ESI=`
_esi: db `00000000`
db ` EDI=`
_edi: db `00000000`
db ` EBP=`
_ebp: db `00000000`
db ` ESP=`
_esp: db `00000000\r\n`
db `CS=`
_cs: db `0000`
db ` DS=`
_ds: db `0000`
db ` ES=`
_es: db `0000`
db ` SS=`
_ss: db `0000`
db ` FS=`
_fs: db `0000`
db ` GS=`
_gs: db `0000\r\n$`
; SHOWEXE.ASM
;
; nasm -fobj showexe.asm -o showexe.obj
; tlink -Tde showexe.obj,showexe.exe
bits 16
%macro dword2hexstr 2
lea di,[%1]
mov eax,%2
call dw2hex
%endmacro
%macro word2hexstr 2
lea di,[%1]
mov ax,%2
call w2hex
%endmacro
section _TEXT
..start:
; Save modified registers
mov [cs:oldESP],esp
mov [cs:oldDS],ds
push _DATA
pop ds
mov [oldEBX],ebx
mov [oldEDI],edi
; Prepare string
lea di,[_eax]
call dw2hex
dword2hexstr _ebx, [oldEBX]
dword2hexstr _ecx, ecx
dword2hexstr _edx, edx
dword2hexstr _esi, esi
dword2hexstr _edi, [oldEDI]
dword2hexstr _ebp, ebp
dword2hexstr _esp, [oldESP]
word2hexstr _cs, cs
word2hexstr _ds, [oldDS]
word2hexstr _es, es
word2hexstr _ss, ss
word2hexstr _fs, fs
word2hexstr _gs, gs
lea dx,[msg]
mov ah,9
int 0x21
mov ax,0x4c00
int 0x21
; Entry: DS:DI points to buffer,
; AL = hexvalue to convert
; Destroys: BX, DI (advances)
b2hex:
movzx bx,al
shr bx,4
mov bl,[bx+hextbl]
mov [di],bl
inc di
movzx bx,al
and bx,0x0f
mov bl,[bx+hextbl]
mov [di],bl
inc di
ret
w2hex:
xchg al,ah
call b2hex
xchg al,ah
call b2hex
ret
dw2hex:
push eax
shr eax,16
call w2hex
pop eax
call w2hex
ret
oldESP: dd 0
oldDS: dw 0
section _DATA
hextbl:
db `0123456789ABCDEF`
oldEBX: dd 0
oldEDI: dd 0
; EAX=00000000 EBX=00000000 ECX=00000000 EDX=00000000
; ESI=00000000 EDI=00000000 EBP=00000000 ESP=00000000
; CS=0000 DS=0000 ES=0000 FS=0000 GS=0000
msg: db `EAX=`
_eax: db `00000000`
db ` EBX=`
_ebx: db `00000000`
db ` ECX=`
_ecx: db `00000000`
db ` EDX=`
_edx: db `00000000\r\n`
db `ESI=`
_esi: db `00000000`
db ` EDI=`
_edi: db `00000000`
db ` EBP=`
_ebp: db `00000000`
db ` ESP=`
_esp: db `00000000\r\n`
db `CS=`
_cs: db `0000`
db ` DS=`
_ds: db `0000`
db ` ES=`
_es: db `0000`
db ` SS=`
_ss: db `0000`
db ` FS=`
_fs: db `0000`
db ` GS=`
_gs: db `0000\r\n$`
Running both:
C:\Work> show
EAX=00000000 EBX=00000000 ECX=000000FF EDX=00000194
ESI=00000100 EDI=0000FFFE EBP=0000091C ESP=0000FFFE
CS=0192 DS=0192 ES=0194 SS=0194 FS=0000 GS=0000
C:\Work> showexe
EAX=00000000 EBX=00000000 ECX=000000FF EDX=00000194
ESI=00000000 EDI=00000000 EBP=0000091C ESP=C67C1818
CS=01A4 DS=C0C2 ES=0194 SS=01A4 FS=0000 GS=0000
Don't take for granted DS, ES or SS on EXE files. And don't take for granted SS on COM and EXE files.
And any other GPRs cannot be taken for granted as well.