2017-2018-1 20152515 《信息安全系统设计基础》第14周学习总结
2017-2018-1 学号 《信息安全系统设计基础》第14周学习总结
教材学习内容总结
这本书中第四章的内容感觉对我来说有点抽象,比如SEQ,比如流水线,觉得自己似懂非懂。所以我今天重新学习这一章。
Y86-64指令
-
movq 前面的两个字母是在显式的指定源操作数和目的操作数的格式,第一位是源操作数,第二位是目的操作数。
- irmovq
- rrmovq
- mrmovq
- rmmovq
-
整数操作指令:它们只对寄存器数据进行操作(IA32允许对存储器数据进行这些操作)。这些指令会设置三个条件码:ZF-零 SF-符号 OF-溢出
- addq
- subq
- andq
- xorq
-
跳转指令:根据分支指令的类型和条件码的设置来选择分支,分支条件和IA32一样。
- jmp
- jle
- jl
- je
- jne- jg
-
条件传送指令: 这些指令的格式与寄存器-寄存器传送指令rrmovl一样,只有当条件码满足所需要的约束时,才会更新目的寄存器的值。
- cmovle
- cmovl
- cmove
- cmovne
- cmovge
- cmovg
-
call指令:call指令将返回地址入栈,然后跳到目的地址,ret 从这样的过程调用中返回。
-
ret指令:从这样的过程调用中返回。
-
pushq/popq:实现入栈和出栈
-
halt指令: 停止指令的执行,执行此指令会导致处理器停止,并将状态码设置为HLT。
SEQ抽象视图
- 硬件结构
Y86异常
值 | 名字 | 含义 |
---|---|---|
1 | AOK | 正常操作(除此之外的任何状态都会使得处理器停止执行指令) |
2 | HLT | 处理器执行halt指令 |
3 | ADR | 遇到非法地址 |
4 | INS | 遇到非法指令 |
新的收获
流水线冒险
关于异常处理的细节问题:
- 三个问题
- 如何通过程序来判断
练习
- 确定下面的Y86指令序列的字节编码。.pos 0x100表明这段代码的起始地址应该是0x100
irmovl $15,%ebx
rrmovl %ebx,%ecx
loop:
rmmovl %ecx,-3(%ebx)
addl %ebx,%ecx
jmp loop
解答:
irmovl $15,%ebx ##30f30f000000
rrmovl %ebx,%ecx ##2031
loop:
rmmovl %ecx,-3(%ebx) ##4013fdffffff
addl %ebx,%ecx ##6031
jmp loop ##7008010000
注意最后一个指令:第一条指令需要6个字节,而第二条指令需要2个字节,因此,循环的目标地址为0x00000108.以反向顺序来写就是08 01 00 00.
- 确定下列每一个字节序列所编码的Y86指令序列。如果有不合法字节,指出其位置。
A.
0x100:30f3fcffffff ##irmovl $-4,%ebx
0x106:406300080000 ##rmmovl %esi,0x800(%ebx)
0x10c:00 ##halt
B.
0x200:a06f ##pushl %esi
0x202:8008020000 ##call proc
0x207:00 ##halt
0x208: ##proc:
0x208:30f30a000000 ##irmovl $10,%ebx
0x20e:90 ##ret
C.
0x300:505407000000 ##mrmovl 0x7(%esp),%ebp
0x306:10 ##nop
0x307:f0 ##非法
0x308:b01f ##popl %ecx
- 修改P238图4-6中的Y86代码,使其能计算一个数组的绝对值的和。内循环中使用条件传送。
源代码:
int Sum(int *Start,int Count)
{
int sum = 0;
while(Count)
{
sum+=*Start;
Start++;
Count--;
}
return sum;
}
改动之后:
loop:
mrmovl (%ecx),%esi
irmovl $0,%edi
subl %esi,%edi
cmovg %edi,%esi
addl %esi,%eax
irmovl $4,%ebx
addl %ebx,%ecx
irmovl $-1,%ebx
addl %ebx,%edx
jne loop
家庭作业
4.43
没有正确执行pushl %esp,pushl %esp是将esp当前的内容入栈。
如果REG是esp,那么代码是先减去了esp,然后将减了4以后的REG移入了esp。
修改:(我只能想到利用其它的寄存器)
movl REG, %eax
subl $4, %esp
movl %eax, (%esp)
4.44
也没有正确执行popl %esp,因为popl %esp是将当前栈顶的值放入esp。
如果REG是esp,那么最后得到esp是栈顶值减4之后的值。
movl (%esp), %eax
addl $4, %esp
movl %eax, REG
4.45
我没有按书上给的例子写,而是自己写了一个冒泡。
void bubble(int *data, int count)
{
if(count == 0) return;
int i, j;
int *p, *q;
for(i=count-1; i!=0; i--){
p = data, q = data + 1;
for(j=0; j!=i; ++j)
{
if( *p > *q )
{
int t = *p;
*p = *q;
*q = t;
}
p++, q++;
}
}
}
Y86:(movl就没有区分那么细了,因为太麻烦了。。。)
data:#(从地地址往高地址)
$5, $2, $7, $4, $3, $6, $1, $8
movl $8, %ecx
pushl %ecx #count = 8
movl data, %ecx
pushl %ecx #push data
call bubble
halt
bubble:
pushl %ebp
movl %esp, %ebp
pushl %esi
pushl %ebx
pushl %edx
movl 8(%ebp), %edx #edx == data
movl 12(%ebp), %esi #esi == count
andl %esi, %esi
je bubbleEnd #count==0
movl $1, %eax
subl %eax, %esi #count--
je bubbleEnd #count==1
OuterLoop:
movl %edx, %ecx # p = data (ecx)
pushl %esi# to save one reg
InnerLoop:
movl (%ecx), %eax
movl 4(%ecx), %ebx
subl %eax, %ebx
movl 4(%ecx), %ebx
jg NoSwap
movl %eax, %ebx #swap, so ebx is greater
movl 4(%ecx), %eax
NoSwap:
movl %eax, (%ecx)
movl %ebx, 4(%ecx)
movl $4, %eax
addl %eax, %ecx
movl $1, %eax
subl%eax, %esi
jne InnerLoop
popl %esi
movl $1, %eax
subl %eax, %esi
jne OuterLoop
bubbleEnd:
popl %edx
popl %ebx
popl %esi
movl %ebp, %esp
popl %ebp
ret
4.46
InnerLoop内改成:(edx是循环利用)
movl (%ecx), %edx
InnerLoop:
movl %edx, %eax
movl 4(%ecx), %ebx
subl %ebx, %eax # compare *p and *(p+1)
cmovl %ebx, %edx #edx is max
movl (%ecx), %eax
cmovg %ebx, %eax #%eax is min
movl %edx, 4(%ecx)
movl %eax, (%ecx)
movl $4, %eax
addl %eax, %ecx
movl $1, %eax
subl %eax, %esi
jne InnerLoop
4.47
我们可以明确的是,这条指令完成的任务为,
ebp <- M4[cur_ebp]
esp <- cur_ebp + 4
取指阶段
icode:ifun = D:0
valP <= PC + 1
译码阶段
valB <= R[%ebp]
执行阶段
valE <= valB + 4
访存阶段
valM <= M4[valB]
写回阶段
R[%esp] <= valE
R[%ebp] <= valM
4.48
取指阶段
icode:ifun = M1[PC] = C:0
rA:rB <= M1[PC+1]
valC <= M4[PC+2]
valP <= PC + 6
译码阶段
valB <= R[rB]
执行阶段
valE <= valB + valC
SetCC
访存阶段
写回阶段
R[rB] <= valE
4.50
取指
bool need_regids =
icode in { IRRMOVL, IOPL, IPUSHL, IPOPL,
IIRMOVL, IRMMOVL, IMRMOVL, IADDL };
bool need_valC =
icode in { IIRMOVL, IRMMOVL, IMRMOVL, IJXX, ICALL, IADDL };
译码和写回
int srcA = [
icode in { IRRMOVL, IRMMOVL, IOPL, IPUSHL } : rA;
icode in { IPOPL, IRET } : RESP;
1 : RNONE; # Don’t need register
];
int srcB = [
icode in { IOPL, IRMMOVL, IMRMOVL, IADDL } : rB;
icode in { IPUSHL, IPOPL, ICALL, IRET } : RESP;
icode in { ILEAVE } : REBP;
1 : RNONE; # Don’t need register
];
int dstE = [
icode in { IRRMOVL} && Cnd : rB;
icode in { IIRMOVL, IOPL, IADDL } : rB;
icode in { IPUSHL, IPOPL, ICALL, IRET, ILEAVE } : RESP;
1 : RNONE; # Don’t write any register
];
int dstM = [
icode in { IMRMOVL, IPOPL}:rA;
icode in { ILEAVE }: REBP;
1 : RNONE; # Don’t write any register
];
执行
int aluA = [
icode in { IRRMOVL, IOPL } : valA;
icode in { IIRMOVL, IRMMOVL, IMRMOVL, IADDL } : valC;
icode in { ICALL, IPUSHL}:-4;
icode in { IRET, IPOPL, ILEAVE}:4;
# Other instructions don’t need ALU
];
int aluB = [
icode in { IRMMOVL, IMRMOVL, IOPL, ICALL,
IPUSHL, IRET, IPOPL, ILEAVE, IADDL } : valB;
icode in { IRRMOVL, IIRMOVL}:0;
# Other instructions don’t need ALU
];
bool set_cc = icode in { IOPL, IADDL };
访存
int mem_addr = [
icode in { IRMMOVL, IPUSHL, ICALL, IMRMOVL } : valE;
icode in { IPOPL, IRET } : valA;
icode in { ILEAVE } : valB;
# Other instructions don’t need address
];
bool mem_read = icode in { IMRMOVL, IPOPL, IRET, ILEAVE };
4.57
A.
发现加载/使用冒险的逻辑公式:
( E_icode in {IMRMOVL, IPOPL} && E_dstM in {d_srcA, d_srcB})
&&
!(E_icode == IMRMOVL && D_icode == IPUSHL);
B.
e_valA = [ (E_icode==IPUSH) && (M_dstM==E_srcA) : m_valM;
1 : E_valA;
];
结对及互评
本周结对学习情况
- [20155232](http://www.cnblogs.com/lsqsjsj/p/8098365.html
- 结对学习内容
- 交流最差的一章学习情况
- 探讨原因
- 交流新的收获
其他(感悟、思考等,可选)
认真回顾自己这一个学期来在这门课上的学习,就会发现,其实有很多需要补充的地方。老师让我们完成一个最差的一章的学习总结,通过这篇博客我们完成了,但是并不意味着我们的学习就没有学的不好的部分了,我们还需要一直地去反思和复习,才能够不断查缺补漏,取得更好的成绩。
学习进度条
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
---|---|---|---|---|
目标 | 5000行 | 30篇 | 400小时 |
| 第四周 | 300/1300 | 2/9 | 30/90 | |
尝试一下记录「计划学习时间」和「实际学习时间」,到期末看看能不能改进自己的计划能力。这个工作学习中很重要,也很有用。
耗时估计的公式
:Y=X+X/N ,Y=X-X/N,训练次数多了,X、Y就接近了。
-
计划学习时间:XX小时
-
实际学习时间:XX小时
-
改进情况:
(有空多看看现代软件工程 课件
软件工程师能力自我评价表)