我有这个机器代码,我过去4天一直在努力,但我似乎无法掌握它。
pushl %ebp
movl %esp, %ebp
jmp .L3
L4:
addl $3,8(%ebp)
L3:
movl 8(%ebp),%eax // having issues here
movzbl (%eax),%eax//here
cmpb $1,%al// and here
je .L5
cmpl 12(%ebp),%eax
jne .L4
movl $8,%eax
.L5: leave
ret
以下是我对解决方案的尝试:
int main(int s, char *t){
while (s != 1) {
if (s == *t){
s = 8;
}
else{s+=3;}
}
return;
}
有人能告诉我,我是否正确接近这个?如果没有帮助我指向正确的方向?
答案 0 :(得分:5)
该函数看起来是__cdecl,因为它引用了8(%ebp)
和12(%ebp)
而没有初始化,这表明它们是参数。分别称他们为arg1
和arg2
。
我们可以注释程序集:
/* Function prologue */
pushl %ebp
movl %esp, %ebp
jmp .L3
L4:
/* Move to next loop iteration */
addl $3, arg1
L3:
/* Copy value of arg1 to %eax */
movl arg1, %eax
/* (%eax) means to dereference %eax (as a memory address).
movzbl means to load a single byte and zero-extend to the rest of the register.
Therefore, the byte at address %eax is put into %eax. */
movzbl (%eax), %eax
/* Compare the low byte of %eax against 1 */
cmpb $1, %al
/* If equal, exit (%eax = 1) */
je .L5
/* Compare %eax against arg2 */
cmpl arg2, %eax
/* If not equal, keep looping */
jne .L4
/* Otherwise, if it was equal, we quit and return %eax = 8 */
movl $8,%eax
.L5: leave
ret
在C代码中,这变为
int fn(unsigned char *ptr, int sentinel) {
while(1) {
unsigned char c = *ptr;
if(c == 1) return c;
if(c == sentinel) return 8;
ptr += 3;
}
}
答案 1 :(得分:3)
以下是反汇编的注释版本:
pushl %ebp // save frame pointer
movl %esp, %ebp // setup new stack frame
// The stack frame looks like this:
// 0(%ebp) : previous frame pointer
// 4(%ebp) : return address
// 8(%ebp) : unsigned char *arg1
// 12(%ebp) : int arg2
jmp .L3 // jump to loop body
L4:
addl $3,8(%ebp) // arg1 += 3
L3:
movl 8(%ebp),%eax // %eax = arg1
movzbl (%eax),%eax // %eax = *arg1 (zero-extend from byte to dword)
cmpb $1,%al // *arg1 == 1?
je .L5
// *arg1 != 1
cmpl 12(%ebp),%eax // arg2 == *arg1?
jne .L4
// *arg1 == arg2
movl $8,%eax // result = 8
.L5: leave
ret
由此,我们可以尝试编写等效的C代码:
int f(unsigned char *p, int v)
{
unsigned char b;
for(; (b = *p) != 1; p += 3) {
if(b == v)
return 8;
}
return b;
}
答案 2 :(得分:1)
更像这样,假设CDECL呼叫标准。
int fn(int s, int t){
for(;*(char*)s != 1 && s != t;s += 3);
if(s == t)
return 8;
else
return s;
}
这是对你说过你没有得到的那些的解释。
movl 8(%ebp),%eax // Load s from stack into register eax.
movzbl (%eax),%eax // Load a byte from the address in eax (s) and set the higher 3 bytes of eax to 0.
cmpb $1,%al // Compare that byte loaded to 1.