
栈机制、逻辑运算、数值处理
1. 逻辑运算指令 这些指令直接对操作数的位 bit 进行运算,是汇编编程的基础工具。 OR 逻辑或 : 规则 :只要有一个为 1,结果即为 1;全 0 则为 0。 应用 :常用于将特定位置 1。 技巧 :在数字转 ASCII 码时,常用 or dl, 0
1. 逻辑运算指令
这些指令直接对操作数的位 (bit) 进行运算,是汇编编程的基础工具。
- OR (逻辑或):
- 规则:只要有一个为 1,结果即为 1;全 0 则为 0。
- 应用:常用于将特定位置 1。
- 技巧:在数字转 ASCII 码时,常用
or dl, 0x30代替加法(前提是 DL 高 4 位为 0)。
- AND (逻辑与):
- 规则:两个都为 1,结果才为 1。
- 应用:用于位屏蔽 (Masking),即将特定位清零而保留其他位。
- XOR (逻辑异或):
- 规则:相同为 0,不同为 1。
- 应用:寄存器快速清零。
xor ax, ax比mov ax, 0指令更短、执行更快。
- 标志位影响:这些指令执行后,
OF和CF强制清零,SF、ZF、PF根据结果设置,AF状态未定义
2. 栈
栈是处理器自动维护的一种“后进先出 (LIFO)”的数据结构。
- 核心寄存器:
SS (Stack Segment):存放栈段的段地址。SP (Stack Pointer):存放栈顶的偏移地址。
- 推进方向:向下增长。即从高地址向低地址推进。
- 操作原理:
- PUSH (压栈):
SP = SP - 2$\rightarrow$ 将字写入SS:SP。 - POP (出栈):从
SS:SP读取字 $\rightarrow$SP = SP + 2。
- PUSH (压栈):
- 初始技巧:
- 若设
SS=0x0000,SP=0x0000,第一次 PUSH 时,SP 减 2 产生借位,指向0xFFFE。这意味着栈是从段的最顶端地址开始使用的。
- 若设
- 强制约束:8086 处理器的 PUSH/POP 必须以字 (16位/2字节) 为单位。
3. 算法逻辑
- 1 到 100 累加求和:
xor ax, ax:累加器清零。mov cx, 1:从 1 开始累加。- 循环体:
add ax, cx$\rightarrow$inc cx$\rightarrow$cmp cx, 100。 - 结果:最终 AX 中存储 5050 ($101 \times 50$)。
- 数值分解与逆序显示 (利用栈):
- 问题:100 累加结果是 5050,除法分解出数字的顺序是
0, 5, 0, 5(从低位到高位),但屏幕显示需要5, 0, 5, 0。 - 方案:将分解出的每个余数依次 PUSH 入栈,分解完成后再依次 POP 出栈显示。利用栈的“先进后出”特性,实现数字顺序的反转。
- 问题:100 累加结果是 5050,除法分解出数字的顺序是
4. 字符串显示与内存布局
- 显存寻址:
- 实模式下,显存起始物理地址通常为
0xB8000。 - 逻辑地址通常设为
ES=0xB800。
- 实模式下,显存起始物理地址通常为
- 字符构成:每个显示字符占 2 字节(低字节为 ASCII 码,高字节为属性字节,如
0x07为黑底白字)。 - LOOP 指令:
- 依赖
CX寄存器。每次执行loop,CX自动减 1。 - 如果
CX \neq 0,则跳转到标签处继续执行。
- 依赖
5. 易错点总结
- 栈平衡:在循环或过程中,PUSH 和 POP 的次数必须严格相等。如果栈不平衡,程序会因为 SP 指向错误或返回地址被破坏而崩溃。
- 指令大小限制:在 16 位处理器上,
push al是非法的,必须压入 16 位寄存器(如push ax)。 - 寄存器保护:在循环体内部,如果需要使用某些会被修改的寄存器,应在循环开始 PUSH 它们,并在末尾 POP 恢复。