ICS Notes

ICS Notes

  • Carry Flag将两个操作数视作无符号数,无符号数加减溢出的时候Carry Flag会被置为1。在实际执行的加法中,如果两个操作数的符号位相等,但不等于结果的符号位,CF会被置为1,反之为0. 在减法中,如果不够减,那么CF被置为1.

CF (bit 0) Carry flag — Set if an arithmetic operation generates a carry or a borrow out of the most significant bit of the result; cleared otherwise.

  • Over Flag将两个操作数视为有符号数。加法时,若CF=1表示加法有进位。减法时,若CF=1表示不够减。

  • SHL 逻辑左移,每左移一次,把最高位移到CF里,并在低位补0
  • SHR 逻辑右移,每右移一次,把最低位移到CF里,并在高位补0
  • SAL 算术左移,和SHL一样,只不过若移位前后sign bit发生变化,那么OF会被置为1
  • SAR 算术右移,每右移一次,把最低位移到CF里,并在高位补符号位
  • ROL 循环左移,每左移一次,把最高位放到最低位,同时把最高位放到CF里
  • ROR 循环右移,每右移一次,把最低位放到最高位,同时把最低位放到CF里
  • RCL 把CF当成最高位加到原来的数左边,一起循环左移。
  • RCR 把CF当成最低位加到原来的数右边,一起循环右移。

  • JCXZ/JECXZ: jump if CX/ECX is 0

  • MUL

    • 单操作数 例如MUL A 意思是DX:AX = (AX * A)
    • 双操作数 例如MUL S, D 意思是 D *= S
    • 三操作数 例如MUL n,S,D 意思是 D = S * n, 这里D必须是寄存器
  • IMUL: 与MUL同理

  • 机器码里面的操作数如果是立即数存储方法也是小端序的,例如e8 6e ff ff ff实际上的操作数是ff ff ff 6e


编译器方面的优化方式:

  1. 提高cache的命中率,例如把二位数组求和改成行优先
  2. 提高流水线的命中率,例如①把循环拆开,②采用cmov指令
  3. 提高单条指令的运行速度,例如把lea 0(%eax,%eax,3) %eax 改为 SAL $2,%eax
  4. 使用串指令,例如在把一个数组的全部赋为0的任务中,使用memset这一封装了串指令的命令
  5. 使用多线程,例如在把一个数组的全部赋为0的任务中,开多个线程分别对数组的各个部分赋0
  6. 使用SIMD:一条指令成组操作,节约了时间
  7. 变量与寄存器绑定

C语言方面的优化方式:

  1. 把*2改为<< 1,提高单调指令的效率

  2. 循环展开,提高流水线效率

  3. 二位数组行优先访问,提高cache命中率

  4. 使用memset等封装了串指令的命令

  5. register int i

  6. if (A && B) 如果A满足概率90%, B 10%,那么写成if (B && A)

  7. 把递归改为迭代

  8. 用封装了SIMD的代码

  9. 多线程

  10. 减少重复计算


异常:CPU内部产生的错误; 中断:由外部设备产生的“外部事件”


Question:

  • rela.data节具体是怎么存储信息的?之前在实验四用readelf看的时候没有看到过rela.data节

    存储信息方式同rela.text;

  • 软中断(int命令)是异常还是中断?

    是异常

  • 栈帧栈顶地址是什么意思?是存返回地址的那个地方是栈顶吗?

    答:不是,是%esp的地址。栈帧的范围是从%ebp到%esp之间(闭区间)

  • 我想要让代码跳到0x4011d6处执行,对应的汇编代码不能直接写jmp 0x4011d6,而是得写成

    考试时可以这样写

    1
    2
    mov $0x4011d6,%r10
    jmp *%r10

    这是为什么?

    另外,如果我新建一个.s文件然后在里面写jmp 0x4011d6然后汇编,然后再反汇编,得到的反汇编结果是jmp 0x05,这是为什么?

  • 一般来说,用switch效率是比用很多if要高吗?

    不一定,按习题来

  • extern定义的变量名会不会出现在符号表里面(因为如果不用就不会)?这种变量是不是没有强弱符号的概念?

  • 在同一个.o文件下,要么全是R_386_32重定位方式,要么全部都是R_386_PC32重定位方式? 看起来不是:(

  • 栈顶是低地址

  • b8 mov literal, a1 mov 直接寻址

  • 外部变量不会在.data,.bss,.text节中

假设LP是一个标号,那么JMP LP等价的语句是:

LEA LP, %EAX

JMP *%EAX

字符之间的比较最好用ja,jb

.data 段里面定义的变量使用的时候可以替换为它的地址。

所有的符号(包括外部符号)只要被引用了就要重定位

如果\(x\)在C语言中是一个无符号数,那么x >>= 1翻译成汇编语言就会时shr

如果\(x\)在C语言中是一个有符号数,那么x >>= 1翻译成汇编语言就会时sar

基址加变址寻址:A(B,C,D)中B和C都必须要是寄存器

没直接问寻址方式就详细答,不放心全都写上

中断描述符表就是中断向量表。