则为0.
零标志Z(ZERO), 若运算结果为0则置1, 否则为0
符号位S(SIGN), 若运算结果的最高位置1, 则该位也置1.
溢出标志O(OVERFLOW), 若(带符号)运算结果超出可表示范围, 则置1.
JXX 系列指令就是根据这些标志来决定是否要跳转, 从而实现条件分枝. 要注意,很多JXX 指令是等价的, 对应相同的机器码. 例如, JE 和JZ 是一样的,都是当Z=1是跳转. 只有JMP 是无条件跳转. JXX 指令分为两组, 分别用于无符号操作和带符号操作. JXX 后面的"XX" 有如下字母:
无符号操作: 带符号操作:
A = "ABOVE", 表示"高于" G = "GREATER", 表示"大于"
B = "BELOW", 表示"低于" L = "LESS", 表示"小于"
C = "CARRY", 表示"进位"或"借位" O = "OVERFLOW", 表示"溢出"
S = "SIGN", 表示"负"
通用符号:
E = "EQUAL" 表示"等于", 等价于Z (ZERO)
N = "NOT" 表示"非", 即标志没有置位. 如JNZ "如果Z没有置位则跳转"
Z = "ZERO", 与E同.
如果仔细想一想,就会发现 JA = JNBE, JAE = JNB, JBE = JNA, JG = JNLE, JGE= JNL, JL= JNGE, .
4. 端口
端口是直接和外部设备通讯的地方。外设接入系统后,系统就会把外设的数据接口映射到特定的端口地址空间,这样,从该端口读入数据就是从外设读入数据,而向外设写入数据就是向端口写入数据。当然这一切都必须遵循外设的工作方式。端口的地址空间与内存地址空间无关,系统总共提供对64K个8位端口的访问,编号0-65535. 相邻的8位端口可以组成成一个16位端口,相邻的16位端口可以组成一个32位端口。端口输入输出由指令IN,OUT,INS和OUTS实现,具体可参考汇编语言书籍。
汇编指令的操作数可以是内存中的数据, 如何让
程序从内存中正确取得所需要的数据就是对内存的寻址。
INTEL 的CPU 可以工作在两种寻址模式:实模式和保护模式。 前者已经过时,就不讲了, WINDOWS 现在是32位保护模式的系统, PE 文件就基本是运行在一个32位线性地址空间, 所以这里就只介绍32位线性空间的寻址方式。
其实线性地址的概念是很直观的, 就想象一系列字节排成一长队,第一个字节编号为0, 第二个编号位1, 。。。。 一直到4294967295(十六进制FFFFFFFF,这是32位二进制数所能表达的最大值了)。 这已经有4GB的容量! 足够容纳一个程序所有的代码和数据。 当然, 这并不表示你的机器有那么多内存。 物理内存的管理和分配是很复杂的内容, 初学者不必在意, 总之, 从
程序本身的角度看, 就好象是在那么大的内存中。
在INTEL系统中, 内存地址总是由"段选择符:有效地址"的方式给出。段选择符(SelectOR)存放在某一个段寄存器中, 有效地址则可由不同的方式给出。 段选择符通过检索段描述符确定段的起始地址, 长度(又