Intel IA-32汇编语言

4

我在将以下Java代码转换为Intel IA-32汇编时遇到了一些困难:

 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;

我的代码正确吗?

注意: 我不允许使用全局变量。

2个回答

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;

非常感谢你,Francisco。如果可以的话,我想问一个问题:在printAdults函数中,“list”被用作输入参数,为什么不进行推送? - Kay

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接