您好我写了一个函数,它通过索引清除数组并生成汇编代码。
_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]中的寄存器。如果寄存器放在方括号中,它是否代表该寄存器的地址?感谢。
答案 0 :(得分:1)
寄存器本身没有地址,但它们可能包含一个到存储位置的地址(指针)。
编译器使用的格式似乎包括参数和局部变量的列表(在顶部)以及它们相对于ebp
中存储的地址的偏移量。
所以mov DWORD PTR _i$[ebp], 0
表示:将0x00000000
存储在地址ebp-8
(本地变量i
所在的位置)。方括号类似于在C中取消引用指针。您需要说明符DWORD PTR
,因为您还可能只想存储单个字节,即0x00
,在这种情况下,您将使用{{1} }}。
BYTE PTR
将mov ecx, DWORD PTR _arr$[ebp]
的双字值移至ebp+8
(正如您从顶部的列表中看到的那样,ecx
对应于_arr
)。就您的C计划而言,8
拥有ebp+8
。美元符号是您使用的特定编译器程序集语法的一个功能。编写该语句的更常见方式是&arr[0]
,但您所拥有的语法具有直接告诉您它所对应的局部变量的优势。
关于循环结构,你应该澄清你的问题到底是什么。