这2章总结的很少,主要是觉得没那么重要。
1.2个操作数的指令,第二个操作数通常是目的操作数:movb a b,move a to b,而add a b,b+=a,指令分为指令类,如mov类:movb,movw,movl,b指一个字节,w表示2个字节,l表示4个字节
movs类(扩展填符号),movz类(扩展填0)
寄存器:这里只说ia32体系的那8个32位寄存器,存数值和指针,都以%e开头,特殊地,最后两个:%esp是栈指针,%ebp是帧指针
指令可以独立地读取或写入前4个寄存器的2个低位字节,如movw %ax,%cx,或movb %al,%cl
所以一般说8个四字节寄存器(%eax),8个双字节寄存器(%ax),8个单字节寄存器(%al),但硬件上只有8个四字节寄存器,后2者是前者的部分
操作数分3类:立即数,即常数值(格式:$0xF);寄存器,表示某个寄存器存的内容(%eax,%ax,%al等);
存储器引用,(格式:4(e1,e2,s)表示操作数的地址是:4+寄存器e1存的内容+寄存器e2存的内容*s:
%eax;$0x11;0x01;(%eax);4(%eax);(%eax,%ecx,3),前2个对应寄存器操作数和立即数操作数,后面的都是存储器引用操作数
2.%esp存的是栈顶指针的值,该值作为地址指向的值是栈顶元素的值,栈顶指针入栈变小,出栈变大;subl $4,%esp表示入栈4个字节,地址+-1表示移动一个字节
(%esp)表示栈顶的地址:movl $0xff,(%esp)表示把0xff覆盖栈顶的四个字节,(%esp)表示%esp所存值作为的地址
3.leal其实是movl的变形:leal s,d:把s加载到d,s就是一个地址(movl是取s所在地址的值),不是没有存储器引用,d必须是寄存器。
4.控制,主要讲了条件跳转指令jmp类和条件传送指令cmov类,忽略,本来以为能看到luajit的一些跳转知识,结果没有。大量if-else不如switch,不过这没什么实际用吧。
(关于条件传送那里我只是略略看,回头认真看一波)
5.第5章:这章备受推崇,但是,我读完了认为几乎没什么收获,说明标题党还是有存在的理由:优化程序的性能
这里主要提了把循环里面一些东西挪到外面,比如for(int i = 0;i < strlen(s);++i),先算strlen,
消除不必要的存储器引用,引入临时变量保存中间结果
循环解开,这个编译器优化做了