2010-11-05 105 views
2

我已经开始学汇编。我遇到了这些线。汇编代码的说明

;*************************************************; 
; Second Stage Loader Entry Point 
;************************************************; 

main: 
    cli ; clear interrupts 
    push cs ; Insure DS=CS 
    pop ds 

在第二行代码中,代码段被推送到堆栈(我认为是这样)。我在许多代码中看到它。为什么我们应该这样做,以及它如何确保DS = CS? DS在第三行弹出堆栈(我认为是这样)。为什么这样做?它弹出堆栈意味着它被推到堆栈之前。没有代码。有人可以向我解释这一切吗?提前致谢。

回答

4

确保这一点不是push cs,它是push cs; pop ds;组合。

第一条指令将当前值cs复制到堆栈中,第二条指令将该值从堆栈中拉出并放入ds寄存器。


响应于您的请求的详细信息,让我们开始以下堆栈和寄存器:

stack=[1,2,3], cs=7, ds=6 

push cs后,其推动cs寄存器的值压入堆栈:

stack=[1,2,3,7], cs=7, ds=6 

pop ds之后,它从堆栈中弹出一个值并将其置于ds寄存器中:

stack=[1,2,3], cs=7, ds=7 

而且基本上就是这样。


我不记得我的头顶部是否有可能与mov指令段寄存器之间传输(我不认为它是,但我可能是错的,而这将需要推/流行顺序)。这link似乎证实:没有mov选项与段寄存器作为源目的地。

但即使是这样,汇编程序员通常会选择更合适的指令,无论是速度还是紧凑代码(或两者),例如使用xor ax, ax而不是mov ax, 0

+0

你能详细解释一下吗?如何推ds; pop cs确保ds = cs? – narayanpatra 2010-11-05 07:00:37

+1

有没有更多的解释,如果你没有看到的重点,这是值得怀疑的,如果你应该学习asm .. – joni 2010-11-05 07:02:26

+0

@paxdiablo:谢谢兄弟。你的解释清除了我的疑惑。 – narayanpatra 2010-11-05 07:23:36

0

通过将CS的值推入堆栈并将其弹出到DS中,可确保DS具有与CS相同的值。

我还没有在汇编程序中编程一段时间,但我认为没有直接的方法从一个段寄存器移动到另一个。

您可以将堆栈视为一堆数据。你把东西推到上面,它会一直保持在那里,直到你弹出它的一堆。这样你就可以使用栈来交换数据。但大多数情况下,您使用它来保存数据,以便您可以将寄存器用于其他目的,并在稍后恢复内容。

执行代码时会发生这种情况。

1)初始情况

CS has value X 
DS has value Y 
Stack has .... 

2)推CS

CS has value X 
DS has value Y 
Stack has ...., X 

3)弹出DS

CS has value X 
DS has value X 
Stack has .... 

但什么是段寄存器。 在过去,8086有16位地址寄存器,但有20位地址空间。因此,他们使用段寄存器通过将段寄存器乘以16将二者组合到20位空间,并添加内存位置。为了节省空间,我们有指针(没有段在段内跳转)和远指针(有段)。

随着80286保护模式的介绍,段寄存器被重新用作段描述符。他们指出了一个记忆位置,它提供了足够的信息来到真实的空间。但是现在我们有了线性地址空间(虚拟映射到真实内存)。

+0

我认为这个术语有点不对。 IIRC CS,DS,...是选择器寄存器,它指向段存储器中的结构描述符。 – ninjalj 2010-11-06 19:06:45

+0

@ninjalj,原来他们在哪里段注册。名字依然存在,功能已经改变。 – 2010-11-06 22:04:25

+0

我指的是这部分:“段寄存器被重新用作段描述符。”段描述符应该是选择器寄存器。 – ninjalj 2010-11-07 01:12:11

4

csds只是寄存器,非常像占位符/变量,更多information about registers read here。在第二行中,您说push cs这意味着您将cs的内容放到堆栈上,并在以下行pop回到ds

刚刚发生的事情是,您将cs复制到ds

push是,说:“把这个堆栈的顶部”

pop的指令,说一旦你做了pop值是“采取从堆栈顶部值”

的指令不再存储在堆栈上。

+0

可能是因为cs和ds是寄存器而不是内存位置,谁知道? – paxdiablo 2010-11-05 07:04:58

+0

不是我,但CS和DS不是内存地址,它们是寄存器。 – 2010-11-05 07:05:01

+0

这是更好的解释之一。他明白我想问的问题用简单的语言解释。可能是cs ds可以是寄存器,但是我理解了pop和push的概念。 – narayanpatra 2010-11-05 07:05:24

0

像在评论中写的,push cs然后pop ds确保ds=cs?push cs将cs的值放在堆栈顶部,然后pop ds从堆栈中删除该值并将其存储在ds中。

1

'将此寄存器压入堆栈,弹出堆栈到此寄存器'有时可以通过MOV指令完成,例如MOV ax,dx。但是一些寄存器到寄存器的MOV指令在指令集中不可用,并且IIRC MOV ds,cs不可用。这可能是把它放在内存中的原因(好,缓存,真的)并将其读回来。