x86 汇编简介
intro to x86 assembly
我正在查看 CSAPP(计算机系统 - 程序员视角 2nd)中关于汇编的示例,我只想知道我对汇编代码的理解是否正确。
练习题3.23
int fun_b(unsigned x) {
int val = 0;
int i;
for ( ____;_____;_____) {
}
return val;
}
gcc C 编译器生成以下汇编代码:
x at %ebp+8
// what I've gotten so far
1 movl 8(%ebp), %ebx // ebx: x
2 movl [=11=], %eax // eax: val, set to 0 since eax is where the return
// value is stored and val is being returned at the end
3 movl [=11=], %ecx // ecx: i, set to 0
4 .L13: // loop
5 leal (%eax,%eax), %edx // edx = val+val
6 movl %ebx, %eax // val = x (?)
7 andl , %eax // x = x & 1
8 orl %edx, %eax // x = (val+val) | (x & 1)
9 shrl %ebx Shift right by 1 // x = x >> 1
10 addl , %ecx // i++
11 cmpl , %ecx // if i < 32 jump back to loop
12 jne .L13
解决方案在同一问题上有类似的 post,但我正在寻找更多的逐行对汇编代码的演练和解释。
你似乎已经明白了指令的意思。但是,7-8
行的注释略有错误,因为分配给 eax
的注释是 val
而不是 x
:
7 andl , %eax // val = val & 1 = x & 1
8 orl %edx, %eax // val = (val+val) | (x & 1)
将其放入 C 模板中可以是:
for(i = 0; i < 32; i++, x >>= 1) {
val = (val + val) | (x & 1);
}
注意 (val + val)
只是左移,所以这个函数所做的是从右边的 x
移出位,然后将它们从右边移入 val
.因此,它正在镜像这些位。
PS:如果for
的主体必须是空的,你当然可以将它合并到第三个表达式中。
我正在查看 CSAPP(计算机系统 - 程序员视角 2nd)中关于汇编的示例,我只想知道我对汇编代码的理解是否正确。
练习题3.23
int fun_b(unsigned x) {
int val = 0;
int i;
for ( ____;_____;_____) {
}
return val;
}
gcc C 编译器生成以下汇编代码:
x at %ebp+8
// what I've gotten so far
1 movl 8(%ebp), %ebx // ebx: x
2 movl [=11=], %eax // eax: val, set to 0 since eax is where the return
// value is stored and val is being returned at the end
3 movl [=11=], %ecx // ecx: i, set to 0
4 .L13: // loop
5 leal (%eax,%eax), %edx // edx = val+val
6 movl %ebx, %eax // val = x (?)
7 andl , %eax // x = x & 1
8 orl %edx, %eax // x = (val+val) | (x & 1)
9 shrl %ebx Shift right by 1 // x = x >> 1
10 addl , %ecx // i++
11 cmpl , %ecx // if i < 32 jump back to loop
12 jne .L13
解决方案在同一问题上有类似的 post,但我正在寻找更多的逐行对汇编代码的演练和解释。
你似乎已经明白了指令的意思。但是,7-8
行的注释略有错误,因为分配给 eax
的注释是 val
而不是 x
:
7 andl , %eax // val = val & 1 = x & 1
8 orl %edx, %eax // val = (val+val) | (x & 1)
将其放入 C 模板中可以是:
for(i = 0; i < 32; i++, x >>= 1) {
val = (val + val) | (x & 1);
}
注意 (val + val)
只是左移,所以这个函数所做的是从右边的 x
移出位,然后将它们从右边移入 val
.因此,它正在镜像这些位。
PS:如果for
的主体必须是空的,你当然可以将它合并到第三个表达式中。