我对组装非常陌生,并尝试通过理解旧的16位dos游戏的反汇编(由IDA Free生成的反汇编)来学习它。
我在该代码中阅读了两件事,我认为,猜到了它的作用。然而,我不确定我是否正确,所以我想检查(这里只是简短的示例代码顺便说一下):
1)
lds di, some_adress ; (eg: ds = 0012h, di=BAF6h afterwards)
xor cx, cx
mov [di], cx ; <- what segment is used here
我猜它使用ds
作为一些神奇的默认段,以应用偏移并计算物理地址。
2)
assume ds:dseg (e.g. 0012h)
mov ax, 0BAF6h ; <- why is the leading 0 here btw
push ds
push ax
所以我的堆栈看起来像:
... ...
02 ds (0012)
00 ax (BAF6) <- sp
然后:
mox bx, sp
les di, ss:[bx]
我想寄存器现在是es
= 0012h
和di
= BAF6h
,这在查看其余游戏代码时会有意义,但是因为我的堆栈看起来像BAF6 0012 ...
,这意味着第一个单词放入di
,而第二个单词放入es
。这让我感到困惑,因为它有点颠倒了两个单词的顺序(从我的角度来看)。
答案 0 :(得分:1)
ds
是除[bp+immediate]
,[bp+si+immediate]
和[bp+di+immediate]
之外的所有其他16位内存寻址模式的默认段。基本上,除非您在间接寻址中使用bp
,否则默认段为ds
。如果您在间接寻址中使用bp
,则默认细分为ss
。
十六进制数中的前导零是许多反汇编程序和汇编程序语法用于将十六进制数与符号分开的约定(其他一些反汇编程序和汇编程序使用0x
而不是0
)。前导零不会影响任何数字的数字值,并且在所有数字系统中都是相同的(二进制,十进制,十六进制等)。
正如您所假设的那样,les
di, ss:[bx]
将第一个单词加载到di
,将第二个单词加载到es
,所以它相当于:
mov di,ss:[bx]
mov es,ss:[bx+2]