我正在学习x86上的汇编,并遇到了一个代码,该代码将所有未初始化变量存储的bss部分归零
;Zero the bss
movw $__bss_start, %di
movw $_end+3, %cx
xorl %eax, %eax
subw %di, %cx
shrw $2, %cx
rep; stosl
但不确定这段代码是如何工作的。可以有人让我知道这里发生了什么事情,第一条指令是将bss段的地址存储到di寄存器但最后三条指令的用途是什么?
答案 0 :(得分: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 stosl
的%eax设置为0,%edi设置为0x4000,%cx设置为4,将内存从0x4000设置为%0x4010为零。
答案 1 :(得分:1)
魔术是rep; stosl
:stosl
将eax
中的4个字节存储到edi
指向的内存中,并将edi
增加4。{ {1}}前缀导致该指令重复,直到rep
中的计数器达到零,并且每次ecx
递减1。
所以我们需要做的就是将.bss段的地址放入ecx
(第一条指令),将4字节字的数放入edi
。这只是ecx
,由剩余的指令计算。