2013-07-08 57 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的倍數,這是你的意思嗎? –