Я читаю книгу Компьютерные системы: взгляд программиста (2-й издание) и практическая задача 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
Проанализируйте работу этого кода, а затем выполните следующие действия:
А. Используйте версию на ассемблере, чтобы заполнить недостающие части кода 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;
}
Объясните мне, пожалуйста, почему у реальной функции нетипичное поведение в этой функции. И я не понимаю, как этот ассемблерный код дает этот оператор val = (val << 1) | (x & 0x1)
val = + val
и подставите его в строку ниже, вы получитеval = (val + val) | (x & 1)
, что, очевидно, совпадает сval = (val << 1) | (x & 0x1)
.leal
ведет себя не совсем обычно. - person harold   schedule 19.05.2013