第四周学习博客20135221黄卫
学习计时:12小时
读书:6小时
代码:2小时
作业:1.5小时
博客:2.5小时
一、学习目标
三种重要的数字表示.
进制转换.进制运算.字.数据大小.寻址和字节顺序.布尔代数.掩码.C语言中的逻辑运算.
C语言中的移位运算.整数的表示.有符号数和无符号数之间的转换.C语言中的有符号数与无符号数.
扩展一个数字的位表示.整数运算.浮点数
二、学习资源
1. 教材:第三章《程序的机器级表示》,详细学习指导见这:重点是3.7,3.11
2. 课程资料:https://www.shiyanlou.com/courses/413 实验四,课程邀请码:W7FQKW4Y
3. 教材中代码运行、思考一下,读代码的学习方法见这。
三、学习方法
1. 进度很重要:必须跟上每周的进度,阅读,练习,问答,项目。我会认真对待每一位同学,请你不要因为困难半途而废。
四、学习任务
1. 阅读教材,完成课后练习(书中有参考答案)
3.1-3.7中练习,重点:3.1,3.3,3.5,3.6,3.9,3.14,3.15,3.16,3.22,3.23,3.27,3.29,3.30,3.33,3.34
2. 考核:练习题把数据变换一下
3. 实验:需要动手的到实验楼中练习一下
4. 深化、实践题目,额外加分
五、后续学习预告(可选):
第四章《处理器体系结构》
六、学习过程
1.程序的机器级表示的历史观点:X86 寻址方式经历三代:
(1)DOS时代的平坦模式,不区分用户空间和内核空间,很不安全
(2)8086的分段模式
(3)IA32的带保护模式的平坦模式
2. ISA:指令集体系结构
ISA包括IA32和x86-64
3.几个处理器:
- 程序计数器(CS:IP)
- 整数寄存器(AX,BX,CX,DX)
- 条件码寄存器(OF,SF,ZF,AF,PF,CF)
- 浮点寄存器
4.寻址和字节顺序
考虑一个w位的整数,位表示位[Xw-1,Xw-2,···,X1,X0],
其中Xw-1是最高有效位,而X0是最低有效位。
如果w为8的倍数,则可将这些位分组为字节,其中最高有效字节包含 位[Xw-1,Xw-2,···,Xw-8],
而最低有效字节包含[X7,X6,···,X0]
★若机器按照从最低有效字节到最高有效字节的顺序存储对象,则称为 小端法。
相反,若机器按照从最高有效字节到最低有效字节的顺序存储对 象则成为大端法。
5.掩码
位向量掩码可以有选择地使能或是不能屏蔽一些信号,其中某一位位置上位1时,
表明信号i是有效的,而0表明该信号是被屏蔽的。即表示的是设置为有效信号的
集合。(对特定位可以置疑,可以清零)
6.整数的表示
具体数据类型的表示范围在教材P38此处不予体现。
要用C99中的"long long"类型,编译要用gcc -std=c99
无符号数的编码:
7.访问信息
IA32的cpu中有8个32位的寄存器,%e是前缀,依次是:ax,cx,dx,bx,si,di,sp,bp。
前6个可以看作是通用寄存器,大多数情况下。前3个和后3个的保存和恢复惯例不同。最后两个指向程序栈中重要位置的指针。
指令的源数据值可以以常数形式给出,或是从寄存器或存储器中读出。也就是,常数,寄存器,内存。
IA32的一条限制:数据传送指令的两个操作数不能都指向存储器位置。
数据传送指令的源操作数在左,目的操作数在右(ATT风格),(Intel风格则相反)。
栈在程序的虚拟地址空间的上部,再往上就是内核虚拟空间了,栈底紧挨着内核虚拟空间,栈顶向下增长。%esp保存这栈顶元素的地址。
将一个双字压入栈,先将%esp减小4,然后将双字放入这多出来的4个字节的空间中。出栈则是先读出4个字节,然后%esp加4。
因为栈和程序代码以及其他形式的程序数据都是放在同样的存储器中(虚拟地址空间),所以程序用标准的存储器寻址方法访问栈内任意位置。
8.算术和逻辑操作
加载有效地址地址指令,leal,只是将源操作数计算出来的地址交给目的操作数,貌似:源操作数是存储器访问格式的,目的操作数是寄存器。
一元操作:incb/w/l,decb/w/l,negb/w/l,notb/w/l,前面两个好理解,第三个是取负,这里用到了一个概念,取负是指2变成-2,-3变成3,可以认为,就
将后面的操作数认为是补码编码的了,然后如果本来是2的补码,现在就要编程-2的补码,也就是进行0-2的运算。第四个是取反。
二元操作:addb/w/l,subb/w/l,imulb/w/l,xorb/w/l,orb/w/l,andb/w/l。12两个是位级的运算,不,其实,所有的都是位级运算,
因为是汇编吗。但值得注意的是:第3个,乘是先数学上的乘,然后截断一下。这是2章中得到的结论,至少是对于imulb/w/l3者。后3个好理解,异或,或,并。
移位:salb/w/l,shlb/w/l,sarb/w/l,shrb/w/l。向左left,向右right移位。向左总是补0的,向右就是算术移位和逻辑移位了。
移位量是单个字节的编码,因为只允许0到31位的移位(只考虑移位量的低五位)。移位量只可以是一个立即数或者单字节寄存器元素%cl。
特别的:imull,mull可以是一元操作(上面的二元操作)。divl和idivl是除法。cltd是符号扩展。这5个是特殊的算术操作。
9. 结合C语言理解控制部分:分支(if/switch),循环语句(while, for)。
控制中最核心的是跳转语句:有条件跳转(实现if,switch,while,for),无条件跳转jmp(实现goto)
10. 有条件跳转的条件看状态寄存器(教材上叫条件码寄存器) 注意leal不改变条件码寄存器
CF:进位标志
ZF:零标志
SF:符号标志
OF:溢出标志
11. 跳转与标号
跳转(jump):导致执行切换到程序中一个全新的位置
标号(label):指明跳转的目的
eg:jmp *%eax
用寄存器%eax中的值作为跳转目标
jmp * (%eax)
以%eax中的值作为跳转目标,从寄存器中读出跳转目标
12. if-else 的汇编结构:
在C语言中test-expr是一个整数表达式,它的取值为0(或“假”)或者非0(或“真”),两个分支语句中只会执行一个。但在汇编实现时,两个分支语句会产生各自的代码。
13. do-while的汇编结构:
在C语言中对于test-expr求值,若求值结果为非零则继续循环,可以看出,它的主体语句至少执行一次。但在汇编实现时,若测试结果为真则回去再执行一次循环。
14. IA32通过栈来实现过程调用。
七、遇到的问题及解决
这次的内容感觉跟上学期的汇编语言的很多内容有些类似,也有一定的结合,这需要我们将二者比较好的结合才能学习好该部分内容
对于C语言中逻辑运算和位运算的内容特别多,也特别杂乱,学起来容易把很多知识点混淆,需要我们学的更仔细来区分这些区别
八、其他