
特殊的算术操作:
两个64位的整数相乘需要128位来表示。x86-64提供将128位的数用八字表示(oct word)的表示方式。操作R需为%rax寄存器,imulq为有符号乘法,mulq为无符号乘法。无符号乘法与有符号乘法截取位数相同时,结果位级行为相同。符号扩展将%rax扩展为128位。
示例代码将%rsi(x)移动到%rax(被乘数),进行128位的乘法,将结果的低8位移动到内存的(%rdi),高8位移动到内存的(%rdi)+8 byte。
除法包括idivl(有符号数除法),128位的被除数(%rdx, %rax)除以一个除数,结果存放在寄存器%rax中,余数存放在%rdx中。无符号除法使用divq指令,寄存器的%rdx会先设置为0。
控制包括直线代码(指令顺序执行)和条件语句、循环语句、分支语句,根据条件判断改变代码执行顺序。机器实现使用jump指令改变指令执行顺序,可以指定控制到程序其他部分。
条件码寄存器(Condition code Register)包括CF(进位标志)、ZF(零标志)、SF(符号标志)、OF(溢出标志)。假设t=a+b(a、b为整型),则CF和OF会设置为0,移位操作会设置CF和OF为0,INC和DEC会设置OF和ZF(溢出:Overflow Flag和零标志Zero Flag)。
CMP指令和TEST指令设置条件码,不改变寄存器,如果两个操作数相同,则将零标志位设置为1,其他标志决定大小关系。testq %rax, %rax检查%rax是否为零或正数。通过testq %al %bl判断%al的%bl掩码位置是否为1。
访问条件码的步骤包括使用SET指令设置字节或低位单字节寄存器(如%al和%bl),或字节内存位置,setl设置小于,seb设置低于。典型指令序列用于表示有符号数和无符号数的比较。
补充:setg和setle是同一条机器指令,表示大于和不大于(就是小于等于),用于有符号数和无符号数的比较。比较溢出和运算结果,使用CF、ZF、SF、OF表示判断结果。
跳转指令(jmp)导致执行切换到程序中的一个新位置,每次跳转用label指明目标。jmp指令直接跳转,目标是部分编码的指令,可以间接跳转,目标是寄存器或内存位置。跳转指令的编码由汇编器和链接器产生,最常用的是地址偏移量或绝对地址。示例汇编代码和反汇编代码用于解释跳转指令的目标编码。
习题涉及根据cmp和set的后缀判断数据长度和类型,例如使用cmpl和setl判断有符号数的long int大小的比较,cmpw和setge判断有符号数的word大小的比较,cmpb和setbe判断无符号数的byte大小的比较,cmpq和setne判断64位quad大小的不等号比较。