2013-07-08 35 views
1

我学习上的x86汇编通过它完成actully归零,所有unintialised变量存储请问这个代码在装配

;Zero the bss 
    movw $__bss_start, %di 
    movw $_end+3, %cx 
    xorl %eax, %eax 
    subw %di, %cx 
    shrw $2, %cx 
    rep; stosl 

但不知道这段代码是如何工作的BSS部分代码来了。任何人都可以让我知道这里发生的事情,第一条指令是将bss段的地址存储到二进制寄存器中,但最后三条指令的目的是什么?

回答

6

就是这样;

;Zero the bss 
movw $__bss_start, %di ; Get start of BSS in %di register 
movw $_end+3, %cx  ; Get end of BSS in %cx register 
xorl %eax, %eax   ; Clear %eax 
subw %di, %cx   ; Calculate size of BSS (%cx-%di) to %cx 
shrw $2, %cx   ; Divide %cx by 4 
rep stosl     ; Repeat %cx times, store %eax (4 bytes of 0) at 
          ; address %di and increase %di by 4. 

关于rep stosl;

  • rep是一个重复前缀,它将重复以下指令(超出有限集合)%cx次。
  • stosl将%eax的值存储在%(e)di指向的地址处,并将%e(di)的值增加%eax的大小。

作为一个例子,与rep stosl%eax中设置为0,%EDI设置为0x4000的和%CX设置为4,将从0x4000的存储器设置为%0x4010到零。

+0

谢谢@Joachim,你能否更具体的关于最后2条指令,并且hwo actully bss正在归零? –

+0

@AmitSinghTomar更新了一些信息。 –

+0

值得一提的是,如果DF标志为0,%e(di)只会递增,如果DF标志为1,则它会递减。您应该有一个'CLD'或'STD'指令来设置方向。另外值得一提的是,'STOS'指令的目标段在es中,如果你正在使用分段内存模型,这可能是相关的。 –

1

神奇的是rep; stoslstosl存储的4个字节中eax到存储器指向edi和增量edi通过4. rep前缀导致要重复该指令直到在ecx计数器达到零,并且每个时间ecx减1。

所以我们所需要做的就是将.bss段的地址放入edi(第一条指令),并将4字节字的数目放入ecx。这只是(bss_start - bss_end) >> 2,它是由剩余的指令计算的。

+0

@Kerek只有一个疑问,为什么它的$ _end + 3,bss应该被标记为_end。 –

+1

@AmitSinghTomar:将四舍五入将填充区*的大小*填充到四的最接近的倍数。 –

+0

得到了你的观点@Kerrek,假设结束地址是41,并且加3以确保它是4的倍数,这是你的意思吗? –