家庭作业汇总

家庭作业:

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

posted @ 2015-11-22 17:49  20135321余佳源  阅读(241)  评论(0编辑  收藏  举报