1

嗨,我编写了一个函数,它通过索引清除数组并生成汇编代码。

_TEXT   SEGMENT
_i$ = -8                        ; size = 4
_arr$ = 8                       ; size = 4
_size$ = 12                     ; size = 4
?clear_arr@@YAXQAHH@Z PROC              ; clear_arr, COMDAT

; 3    : void clear_arr(int arr[], int size){

push    ebp
mov ebp, esp
sub esp, 204                ; 000000ccH
push    ebx
push    esi
push    edi
lea edi, DWORD PTR [ebp-204]
mov ecx, 51                 ; 00000033H
mov eax, -858993460             ; ccccccccH
rep stosd

; 4    :    int i;
; 5    :    for(i = 0; i < size; i++){

mov DWORD PTR _i$[ebp], 0
jmp SHORT $LN3@clear_arr
$LN2@clear_arr:
mov eax, DWORD PTR _i$[ebp]
add eax, 1
mov DWORD PTR _i$[ebp], eax
$LN3@clear_arr:
mov eax, DWORD PTR _i$[ebp]
cmp eax, DWORD PTR _size$[ebp]
jge SHORT $LN4@clear_arr

; 6    :        arr[i]=0;

mov eax, DWORD PTR _i$[ebp]
mov ecx, DWORD PTR _arr$[ebp]
mov DWORD PTR [ecx+eax*4], 0

; 7    :    }

jmp SHORT $LN2@clear_arr
$LN4@clear_arr:

; 8    : }

pop edi
pop esi
pop ebx
mov esp, ebp
pop ebp
ret 0
?clear_arr@@YAXQAHH@Z ENDP              ; clear_arr
_TEXT   ENDS
END

我需要一些关于循环部分的解释。我想知道的另一件事是关于 DWORD PTR 和方括号行 [ebp] 中的寄存器。如果寄存器放在方括号中,它是否代表该寄存器的地址?谢谢。

4

1 回答 1

3

寄存器本身没有地址,但它们可以保存指向内存位置的地址(指针)。

您的编译器使用的格式似乎包括参数和局部变量的列表(在顶部)以及它们相对于存储在ebp.

所以mov DWORD PTR _i$[ebp], 0意味着:存储0x00000000在地址ebp-8(这是局部变量i所在的位置)。方括号类似于取消引用 C 中的指针。您需要说明符DWORD PTR,因为您可能还想简单地存储单个字节,即0x00,在这种情况下您将使用BYTE PTR.

mov ecx, DWORD PTR _arr$[ebp]将 dword 值移动ebp+8ecx(从顶部的列表中可以看到,_arr对应于8)。就您的 C 程序而言,ebp+8持有&arr[0]. 美元符号是您使用的特定编译器汇编语法的一个特性。编写该语句的更常见方法是mov ecx, DWORD PTR [ebp+8],但是您拥有的语法具有直接告诉您它对应于哪个局部变量的优点。

关于循环构造,您可能应该澄清您的问题到底是什么。

于 2013-10-13T18:41:06.790 回答