计算机中的负数

计算机中的负数

sub指令

1
sub 寄存器/内存 寄存器/内存/立即数

将左操作数减去右操作数结果保留在左操作数中

两个操作数宽度必须一致且不可同时为内存地址

neg指令

1
neg 寄存器/内存

计算 0 - 操作数,并将结果写回操作数中

无符号与有符号的运算

1
2
mov ax , -1
mob ax , 65535

这两条指令导致ax内全为1,但是ax到底表示 -1 还是 65535呢?解释很简单,计算机只是机器并不关心,程序由程序员编写,一个数是否有符号程序员应该清楚

1
2
3
4
5
mov ah , 0xf0  ;11110000 可以解释为240 / -16
inc ah ;11110001 可以解释为241 / -15

mov ah , 0xf0
add ah , 0x03 ;11110011 可以解释为243 / -13
  • 对于大多数指令既适用于无符号整数,也适用于有符号整数。指令执行的结果不管是用无符号整数来解释还是用用符号整数来解释都是正确的
  • 但是也有一些指令不能同时应付无符号数和有符号数,需要根据实际情况选择对应的是否有符号版本,如:无符号数乘法mul有符号乘法imul,以及无符号除法div有符号除法idiv

idiv指令

1
idiv 寄存器/内存

规则诶呀div指令相同

  • 如果被除数和除数的符号相同,商为正数,否则商为负数
  • 余数的符号始终和被除数相同

符号扩展

1
2
3
mov ax , -6002
mov bx , -10
idiv bx

在执行idiv之前要将ax的符号位扩展到dx上,使用以下指令

  • cbw : 将AL中的有符号数扩展到AX
  • cwde:将AX中的有符号数扩展到EAX
  • cdqe: 将EAX中的有符号数扩展到RAX
  • cwd: 将AX中有符号数扩展到DX:AX
  • cdq: 将EAX中有符号数扩展到EDX:EAX
  • cdo: 将RAX中有符号数扩展到EDX:RAX
1
2
3
4
mov ax , -6002
cwd
mov bx , -10
idiv bx

flag寄存器

CF(Carry Flag)进位标志:当一个算术操作在结果的最高位产生进位或者借位时,此标志是1否则是0

AL 内容是二进制 1000 0000 执行指令 add al , al 后,CF = 1

PF(parity Flag)奇偶标志:当一个算数操作数的结果在低8位中有偶数个1,此标志为1否则为0

若AL中内容是二进制 0010 0110 则指令

xor al , 3 执行后PF=0

OF(Overflow Flag)溢出标志位:对任何一个算数操作,假定它进行的是有符号运算。那么,当结果超出目标位置所能容纳的最大正数或者最小负数时,此标志为1,表示有符号整数运算结果以及溢出,否则为0

若AH中内容时二进制 1111 1101 则指令

add ah , 5 执行后,OF = 0

ZF(Zero Flag)零标志:当运算结果为0时,此标志为1,否则为0

mov ax , 25

sub ax , 25 ;此指令执行后 ZF = 1

SF(Sign Flag):用运算结果的最高位来设置此标志位(一般来说,这一位是有符号数的符号位,0表示正数,1表示负数)

mov ah , 127

add ah , 1 ;此指令执行后,SF=1

AF(Adjust Flag):当一个算术操作在结果的位3产生进位或者借位时,此标志是1否则是0。此标志用于二进制编码的十进制算法里(BCD编码),用的很少

现有指令对标志位的影响:

  • cbw/cwde/cdqe/cwd/cdq/cqo(位拓展指令),不影响任何标志位
  • cld:DF=0,对CF OF ZF SF AF PF的影响未定义
  • std:DF=1,不影响其他标志位
  • inc/dec:CF标志不受影响,对OF SF ZF AF PF的影响依据计算结果
  • add/sub:OF SF ZF AF CF PF 的状态依据计算结果而定
  • div/idiv:对CF OF SF ZF AF PF 的影响未定义
  • mov/movs:不影响任何标志位
  • neg:如果操作数为,则CF=0,否则CF=1,对OF SF ZF AF PF的影响依据计算结果
  • xor:OF=0 CF=0 对SF ZF PF依照计算结果

条件转移指令

  • js: 符号标志 SF 为1则转移
    jns:符号标志 SF 为0则转移
  • jz: 零标志ZF为1则转移
    jnz:零标志ZF为0则转移
  • jo: 溢出标志位OF为1则转移
    jno:溢出标志位OF为1则转移
  • jc: 进位标志位CF为1则转移
    jnc:进位标志位CF为0则转移
  • jp: 奇偶标志PF为1则转移
    jnp:奇偶标志PF为0则转移
  • jcxz(jump if CX is Zero):当CX寄存器中的内容为0时则转移。执行这条指令时,处理器先测试CX是否为0
    jcxz show ;若cx为0转移到标号show

转移指令本身不影响任何标志位

cmp指令

1
cmp 寄存器/内存 , 寄存器/内存/立即数

cmp指令与sub指令相似,只是不保留计算结果,只设置标志位

常与条件转移指令结合使用:

1
2
cmp dh , 0
jl

JE、JZ:结果为零则跳转(相等时跳转)ZF=1
JNE、JNZ:结果不为零则跳转(不相等时跳转) ZF=0
JS :结果为负则跳转SF=1
JNS :结果为非负则跳转SF=0
JP, JPE:结果中1的个数为偶数则跳转PF=1
JNP, JPO:结果中1的个数为偶数则跳转PF=0
JO:结果溢出了则跳转OF=1
JNO:结果没有溢出则跳转OF=0
JB, JNAE:小于则跳转 (无符号数)CF=1
JNB, JAE:大于等于则跳转 (无符号数)CF=0
JBE, JNA:小于等于则跳转 (无符号数)CF=1 or ZF=1
JNBE, JA:大于则跳转(无符号数)CF=0 and ZF=0
JL, JNGE:小于则跳转 (有符号数)SF≠ OF
JNL, JGE:大于等于则跳转 (有符号数)SF=OF
JLE, JNG:小于等于则跳转 (有符号数)ZF=1 or SF≠ OF
JNLE, JG:大于则跳转(有符号数)ZF=0 and SF=OF