将以下java代码转换为Intel IA-32 Assembly时遇到了一些困难:
class Person() {
char name [8];
int age;
void printName() {...}
static void printAdults(Person [] list) {
for(int k = 0; k < 100; k++){
if (list[k].age >= 18) {
list[k].printName();
}
}
}
}
我的尝试是:
Person:
push ebp; save callers ebp
mov ebp, esp; setup new ebp
push esi; esi will hold name
push ebx; ebx will hold list
push ecx; ecx will hold k
init:
mov esi, [ebp + 8];
mov ebx, [ebp + 12];
mov ecx, 0; k=0
forloop:
cmp ecx, 100;
jge end; if k>= 100 then break forloop
cmp [ebx + 4 * ecx], 18 ;
jl auxloop; if list[k].age < 18 then go to auxloop
jmp printName;
printName:
auxloop:
inc ecx;
jmp forloop;
end:
pop ecx;
pop ebx;
pop esi;
pop ebp;
我的代码是否正确?
注意: 我不允许使用全局变量。
答案 0 :(得分:2)
你有一点错误,首先,你编码它就像你得到一个名字和年龄作为参数,你不是,你只需要ebx将地址保存到列表中。假设字符为1个字节(因此在数组中为8个字节),整数和指针为4个字节,这可能会有效:
Person:
push ebp; save callers ebp
mov ebp, esp; setup new ebp
init:
mov ebx, [ebp + 4];
mov ecx, 0; k=0
forloop:
cmp ecx, 100;
jge end; if k>= 100 then break forloop
cmp [ebx + 8 + 12 * ecx], 18 ; 12 * ecx to advance 12 bytes (8 char 4 int), plus 8 to compare the integer, which is 8 bytes away from the start of the pointer.
jl auxloop; if list[k].age < 18 then go to auxloop
jmp printName;
printName:
auxloop:
inc ecx;
jmp forloop;
end:
pop ebp;
答案 1 :(得分:1)
这是我的版本,应该快一点(使用堆栈帧指针,可能会删除:P)
_start:
PUSH EBP
MOV EBP,ESP
PUSH EDI
PUSH ESI
MOV ESI, [EBP + 8] ; __stdcall assumed -> get arg: list
MOV EDI, 100 ; i=100 -> iterations of the loop
_loop:
CMP [ESI + 8], 18 ; pPerson->age >= 18
JL _next
MOV ECX,ESI
CALL printName ; __thiscall assumed
_next:
ADD ESI,12 ; list += sizeof(person)
SUB EDI,1 ; i--
JNZ _loop
_end:
POP ESI
POP EDI
POP EBP
RETN 4