|
网站菜单
|
日记 - 计算机底层入门-A-01
Greeting and welcome.欢迎打开这篇文章,这篇文章是《计算机基本入门》-16位卷的的第一篇。 本系列文章主要教学16位汇编,您需要准备Microsoft Disk Operating System 6.22和Microsoft Macro Assembler。 前言 略 编者简介 略 第一章 初试汇编 简述 略 0.术语表 寄存器 (Register):CPU 内部自带的存储单元。 8086 CPU:Intel 在 1978 年推出的处理器。16 位汇编就是针对这款处理器的指令集编写的。 16 位 (16-bit):指 CPU 一次能处理的数据宽度。这意味着寄存器的大小是 16 个二进制位,能表示的无符号整数范围是 0 到 65535 (216−1)。 堆栈 (Stack):内存中一块特殊的区域,遵循“后进先出”原则。就像洗盘子,最后放上去的盘子必须最先拿走。汇编中用 PUSH 放进去,POP 拿出来。 内存地址 (Address):内存中每个字节的“位置”。 段 (Segment):在 16 位模式下,CPU 无法直接访问超过 64KB 的连续内存。因此,内存被分成多个“段”,每个段最大 64KB。 CS (Code Segment):代码段,存放程序指令。 DS (Data Segment):数据段,存放全局变量。 SS (Stack Segment):堆栈段,存放临时数据。 偏移地址 (Offset):相对于段起始位置的距离。 物理地址计算:在 DOS 中,物理地址 = 段地址×16+偏移地址。例如,1000:0005 指的是物理地址 10005h。 操作码 (Opcode):指令的动作部分。如 MOV(移动)、ADD(加法)。 操作数 (Operand):指令处理的对象。比如 MOV AX, 5 中,AX 和 5 都是操作数。 立即数 (Immediate):代码中直接写死的数值(常数),如 MOV AX, 10 中的 10。 标志位 (Flags):CPU 内部的一个特殊寄存器。 ZF (Zero Flag):如果上次计算结果为 0,它就变成 1。 CF (Carry Flag):如果计算产生了进位,它就变成 1。 标号 (Label):你在代码中给某一行起的名字(如 PRINT_START:),本质上它代表了那行代码在内存中的地址,方便跳转执行。 汇编 (Assembling):将你写的文本代码(.ASM)翻译成机器能读懂的二进制代码(.OBJ)的过程。 链接 (Linking):将一个或多个 .OBJ 文件组合成最终可执行文件(.EXE 或 .COM)的过程。 中断 (Interrupt/INT):一种“暂停当前任务,去处理紧急事务”的机制。 在 DOS 中,INT 21h 是最重要的系统调用。当你执行它时,CPU 会跳到 DOS 系统预设的一段程序里,帮你完成“显示文字”或“保存文件”等复杂操作。 伪指令 (Directive):写给汇编器看的指令,而不是给 CPU 看的。 例如 .DATA、.MODEL SMALL、END。它们不会被转换成机器码,只是告诉 MASM 如何组织代码。 1.指令的基本格式 在 MASM 中,指令通常遵循:操作码 (Opcode) 目的操作数 (Dest), 源操作数 (Src)。 2.数据传输指令 MOV (Move): 复制数据。 MOV AX, 4C00h:立即数传给寄存器。 MOV DS, AX:寄存器传给段寄存器(注意!:不能直接把立即数传给 DS,必须经由 AX 中转)。 XCHG (Exchange): 交换两个操作数的值。 XCHG AX, BX:交换 AX 和 BX 的内容,不需要中间变量。 PUSH / POP: 堆栈操作。 PUSH AX:将 AX 压入栈(SP 减 2)。 POP BX:从栈顶弹出数据到 BX(SP 加 2)。 LEA (Load Effective Address): 装入有效地址。 LEA DX, buffer:将 buffer 变量的偏移地址送入 DX。这在调用 DOS 中断显示字符串是必须的。 3.算术运算指令 ADD / SUB: 加减法。 会影响程序状态字(Flags),如 ZF(零标志)和 CF(进位标志)。 INC / DEC: 加 1 和减 1。 常用于循环计数或指针移动。 MUL / IMUL: 无符号/有符号乘法。 MUL BL:结果存放在 AX。 MUL BX:结果存放在 DX:AX(高 16 位在 DX,低 16 位在 AX)。 DIV / IDIV: 除法。 DIV BL:AX 除以 BL,商在 AL,余数在 AH。 4.逻辑与位移指令 AND / OR / XOR / NOT: 位逻辑。 AND AL, 0DFh:将小写字母转换为大写(通过屏蔽位)。 XOR AX, AX:将寄存器清零的最快方法。 SHL / SHR: 逻辑左/右移。 每左移一位相当于乘以 2,右移一位相当于除以 2。 5.控制流指令 CMP (Compare): 比较。 实质是做减法,但不保存结果,只根据差值修改 Flags(标志寄存器)。 条件跳转 (JZ, JNZ, JG, JL, JC, JNC): JZ (Jump if Zero):如果上次结果为 0 则跳。 JNC (Jump if No Carry):如果没有进位则跳。 JMP: 无条件跳转。 LOOP: 循环控制。 它查看 CX 寄存器。每次执行,CX 自动减 1,只要 CX != 0 就跳回标号处。 6.程序结构解析 ; 示例程序 .MODEL SMALL ; 定义内存模型 .STACK 100H ; 定义栈大小 .DATA ; 数据段:存放变量 count DB 5 ; 定义一个字节变量,初始值为 5 msg DB 'Looping...', 0Dh, 0Ah, '$' .CODE ; 代码段 MAIN PROC MOV AX, @DATA ; 初始化 DS(必须步骤!!!) MOV DS, AX MOV CX, 5 ; 将循环次数 5 放入计数器 CX PRINT_START: ; 这是一个标号(Label) LEA DX, msg ; 获取字符串地址 MOV AH, 09h ; DOS 功能号:显示字符串 INT 21h ; 调用 DOS 中断 LOOP PRINT_START ; CX 自动减 1,如果不为 0 则跳回 PRINT_START ; 退出程序 MOV AX, 4C00h INT 21h MAIN ENDP END MAIN 解释: .MODEL SMALL: 告诉编译器代码和数据各占一个 64KB 的段,这是最常用的模式。 MOV AX, @DATA: 在 MASM 中,你必须手动加载数据段地址到 DS。这是非常重要的一步!漏掉它会导致程序找不到变量。 INT 21h: DOS 的“函数入口”。AH 里的值决定了它做什么(09h 是打印,4Ch 是退出)。 评论: (6) |