私は本 Computer Systems: A Programmer's Perspective (2nd Edition) と Practice Problem 3.23 を読んでいて、少し混乱しています:
関数 fun_b の全体的な構造は次のとおりです。
int fun_b(unsigned x) {
int val = 0;
int i;
for ( ____;_____;_____) {
}
return val;
}
gcc C コンパイラは、次のアセンブリ コードを生成します。
x at %ebp+8
1 movl 8(%ebp), %ebx
2 movl $0, %eax
3 movl $0, %ecx
.L13:
5 leal (%eax,%eax), %edx
6 movl %ebx, %eax
7 andl $1, %eax
8 orl %edx, %eax
9 shrl %ebx Shift right by 1
10 addl $1, %ecx
11 cmpl $32, %ecx
12 jne .L13
このコードの操作をリバース エンジニアリングしてから、次の操作を行います。
A. アセンブリ コード バージョンを使用して、C コードの欠落部分を埋めます。
私の解決策。
int fun_b(unsigned x) {
int val = 0;
int i;
for ( i = 0 ;i < 32;i++) {
val += val; //because leal (%eax,%eax), edx --> %edx = %eax + %eax
val = val | x & 0x1;
x >>= 1;
}
return val;
}
本の解決策。
int fun_b(unsigned x) {
int val = 0;
int i;
for (i = 0; i < 32; i++) {
val = (val << 1) | (x & 0x1);
x >>= 1;
}
return val;
}
leal 関数がこの関数で非典型的な動作をする理由を説明してください。そして、このアセンブリコードがこのステートメントを生成する方法を理解していませんval = (val << 1) | (x & 0x1)