栈机制、逻辑运算、数值处理

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, axmov ax, 0 指令更短、执行更快。
  • 标志位影响:这些指令执行后,OFCF 强制清零,SFZFPF 根据结果设置,AF 状态未定义

2. 栈

栈是处理器自动维护的一种“后进先出 (LIFO)”的数据结构。

  • 核心寄存器
    • SS (Stack Segment):存放栈段的段地址。
    • SP (Stack Pointer):存放栈顶的偏移地址。
  • 推进方向向下增长。即从高地址向低地址推进。
  • 操作原理
    • PUSH (压栈)SP = SP - 2 $\rightarrow$ 将字写入 SS:SP
    • POP (出栈):从 SS:SP 读取字 $\rightarrow$ SP = SP + 2
  • 初始技巧
    • 若设 SS=0x0000, SP=0x0000,第一次 PUSH 时,SP 减 2 产生借位,指向 0xFFFE。这意味着栈是从段的最顶端地址开始使用的。
  • 强制约束:8086 处理器的 PUSH/POP 必须以字 (16位/2字节) 为单位。

3. 算法逻辑

  • 1 到 100 累加求和
    1. xor ax, ax:累加器清零。
    2. mov cx, 1:从 1 开始累加。
    3. 循环体:add ax, cx $\rightarrow$ inc cx $\rightarrow$ cmp cx, 100
    4. 结果:最终 AX 中存储 5050 ($101 \times 50$)。
  • 数值分解与逆序显示 (利用栈)
    • 问题:100 累加结果是 5050,除法分解出数字的顺序是 0, 5, 0, 5(从低位到高位),但屏幕显示需要 5, 0, 5, 0
    • 方案:将分解出的每个余数依次 PUSH 入栈,分解完成后再依次 POP 出栈显示。利用栈的“先进后出”特性,实现数字顺序的反转。

4. 字符串显示与内存布局

  • 显存寻址
    • 实模式下,显存起始物理地址通常为 0xB8000
    • 逻辑地址通常设为 ES=0xB800
  • 字符构成:每个显示字符占 2 字节(低字节为 ASCII 码,高字节为属性字节,如 0x07 为黑底白字)。
  • LOOP 指令
    • 依赖 CX 寄存器。每次执行 loopCX 自动减 1。
    • 如果 CX \neq 0,则跳转到标签处继续执行。

5. 易错点总结

  1. 栈平衡:在循环或过程中,PUSH 和 POP 的次数必须严格相等。如果栈不平衡,程序会因为 SP 指向错误或返回地址被破坏而崩溃。
  2. 指令大小限制:在 16 位处理器上,push al 是非法的,必须压入 16 位寄存器(如 push ax)。
  3. 寄存器保护:在循环体内部,如果需要使用某些会被修改的寄存器,应在循环开始 PUSH 它们,并在末尾 POP 恢复。