家庭作业汇总
家庭作业:
2.65 写出代码实现如下函数:
/Return 1 when x contains an even number of 1s; 0 otherwise. Assume w=32/
int even_ones(unsigned x);
函数应该遵循位级整数编码规则,不过你可以假设数据类型int有w=32位,你的代码最多只能包含12个算术运算、位运算和逻辑运算。
解读题目:当无符号数x包含偶数个1时,返回值为1,否则为返回值为0,假设x的数据类型是int 有w=32位。
解题思路:要求x所包含的1的个数,可以对x的每个位进行异或运算。如果得到的结果是0,那么就说明x包含偶数个1,则返回值为1,;如果得到的结果是1,那么说明x包含奇数个1,则返回值为0。
代码编写过程:由于x是个32位int类型数,所以①首先采用折半缩小规模的方法进行逐位异或。②最后得到的x值再与1进行与运算就会得到一个32位中前31均为0,尾数是0或者是1(用于判断是原x包含奇数还是偶数个1),③返回这个值就完成了题目需求。
代码编写:
int even_ones(unsigned x){
x ^= (x >> 16);//等同于x=x^(x>>16)
x ^= (x >> 8); //等同于x=x^(x>>8)
x ^= (x >> 4); //等同于x=x^(x>>4)
x ^= (x >> 2); //等同于x=x^(x>>2)
x ^= (x >> 1); //等同于x=x^(x>>1)
return !(x&1);
}
截图:
结果:
即当a为10e5+0时,返回值为0
若a为10e5+1时,返回值为1
家庭作业3.60
解析:A:参考二维数组
B:汇编代码解析:
第1行:i
第2行:j
第3行:9j
第4行:i的值赋给edx
第5行:把edx的值向左移64位,因为2^6=64
第6行:64i-i=63i赋给edx
第7行:63i+9j
第8行:63i+9j+k
第9行:A+4(63i+9j+k) 等价于A+4(iST+j*T+k)
第10行:将dest指针赋给eax
第11行:将dest指向%edx的内容
第12行:2772即A[R][S][T]的大小
由汇编代码可知:
A+4(63i+9j+k) 等价于A+4(iST+j*T+k)
S*T = 63;
T = 9;
RST = 2772/4;
所以得 R=11, S=7, T=9。
-
- 4.46
修改对家庭作业4.45所写的代码,用条件传送来实现冒泡排序函数的内循环中的测试和交换。
该冒泡排序的内循环是:
for(j=0; j!=i; ++j)
{
if( *p > *q )
{
int t = *p;
*p = *q;
*q = t;
}
p++, q++;
}
根据C语言的内循环结构,可以进行改写成以下的内循环汇编代码:
InnerLoop内改成:(edx循环利用)
movl (%ecx), %edx
InnerLoop:
movl %edx, %eax //将%edx存储的值赋给%eax
movl 4(%ecx), %ebx
subl %ebx, %eax //比较%ebx所存储的指针p的值与%eax中所存储的(p+1)的值,相当于C语句的条件表达式中的p>(p+1)?(p<(p+1))😦p>(p+1))中问号前的部分
cmovl %ebx, %edx //比较出来得到%ebx所存储的*p小于%edx存储的值,即%edx是存储的是最大的值
movl (%ecx), %eax //把%ecx地址值赋给%eax
cmovg %ebx, %eax //比较出来得到%ebx所存储的*p大于%eax的值,即%eax所存储的是最小的值
movl %edx, 4(%ecx)
movl %eax, (%ecx) //将%eax的值指向%ecx
movl $4, %eax //初始化%eax为4
addl %eax, %ecx
movl $1, %eax //把%eax的值赋为1
subl %eax, %esi //计算%eax - %esi并作为返回值
jne InnerLoop