I am very new to assembly, and try to learn it by understanding a disassembly of an old 16-bit dos game (disassembly generated by IDA Free).
There are 2 things I read in that code and I think, guessed what it does. Nevertheless I am not really sure if I'm correct, so I wanted to check (just shortened example code here btw):
1)
lds di, some_adress ; (eg: ds = 0012h, di=BAF6h afterwards)
xor cx, cx
mov [di], cx ; <- what segment is used here
I guess its using the ds
as some magic default segment, to apply the offset and calculate the physical adress.
2)
assume ds:dseg (e.g. 0012h)
mov ax, 0BAF6h ; <- why is the leading 0 here btw
push ds
push ax
so my stack is looking like:
... ...
02 ds (0012)
00 ax (BAF6) <- sp
then:
mox bx, sp
les di, ss:[bx]
I guess the registers are now es
=0012h
and di
=BAF6h
, which would make sense when looking at the rest of the games code, but since my stack is looking like BAF6 0012 ...
, this would mean that the first word is put into di
while the second word is put into es
. This confuses me a bit, since it's kinda reversing the order of the two words (from my point of view).
ds
is the default segment for all other other 16-bit memory addressing modes except [bp+immediate]
, [bp+si+immediate]
and [bp+di+immediate]
. So basically, unless you use bp
in indirect addressing, the default segment is ds
. If you use bp
in indirect addressing, then the default segment is ss
.
A leading zero in hexadecimal numbers is a convention used by many disassemblers and assembler syntaxes to separate hexadecimal numbers from symbols (some other disassemblers and assemblers use 0x
instead of 0
). Leading zeros do not affect the numeric value of any number, and it's the same in all number systems (binary, decimal, hexadecimal, etc.).
Just as you assume, les
di, ss:[bx]
loads the first word into di
and and the second word into es
, so it's equivalent to:
mov di,ss:[bx]
mov es,ss:[bx+2]