汇编语言程序实际架构。
 
基本知识篇 常用DEBUG指令 -r 显示 CPU 寄存器值
-t 单步执行,同时显示新寄存器值
-d xxxx 查看内存地址
-u 显示接下来的指令
-g xxxx 指令跳转
寄存器显示中,各标志位代码对应值如下:
汇编语言源程序框架 MASM 6.x 版本简化段定义的源程序框架  :
1 2 3 4 5 6 7 8 9 10 .model small            ; 定义程序存储模式 (small 表示小型模式) .stack                    ; 定义堆栈段 (默认 1KB 空间) .data                    ; 定义数据段 ...                        ; 数据定义 .code                    ; 定义代码段 .startup                ; 程序起始点,并设置DS和SS内容 ...                        ; 主程序代码 .exit 0                    ; 程序终止点,返回DOS ...                        ; 子程序代码 end                        ; 汇编结束 
以输出 “Hello, world!” 为例展示完整代码:
1 2 3 4 5 6 7 8 9 10 11 .model small            ; 定义程序存储模式 (small 表示小型模式) .stack                    ; 定义堆栈段 (默认 1KB 空间) .data                    ; 定义数据段     string db 'Hello, world!', 0dh, 0ah, '$' .code                    ; 定义代码段 .startup                ; 程序起始点,并设置DS和SS内容     mov dx, offset string     mov ah, 9     int 21h .exit 0                    ; 程序终止点,返回DOS end                        ; 汇编结束 
任何版本都能使用的完整段定义的源程序框架  :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 stack   segment stack        ; 定义堆栈段         ...                    ; 分配堆栈段大小 stack   ends                ; 堆栈段结束 data    segment                ; 定义数据段         ...                    ; 定义数据 data    ends                ; 数据段结束 code    segment 'code'        ; 定义代码段         assume cs:code, ds:data, ss:stack    ; 确定cs/ds/ss指向的逻辑段 start:  mov ax, data        ; 定义数据段的段地址ds         mov ds, ax         ...                    ; 主程序代码         mov ax, 4cc00h                 int 21h                ; 程序执行终止,返回DOS         ...                    ; 子程序代码 code    ends                ; 代码段结束         end start            ; 汇编结束,程序起始点为start 
上述输出 “Hello, world!” 的代码改写为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 stack   segment stack        ; 定义堆栈段         db 1024 dup(?) stack   ends                ; 堆栈段结束 data    segment                ; 定义数据段         string db 'Hello, world!', 0dh, 0ah, '$' data    ends                ; 数据段结束 code    segment 'code'        ; 定义代码段         assume cs:code, ds:data, ss:stack    ; 确定cs/ds/ss指向的逻辑段 start:  mov ax, data        ; 定义数据段的段地址ds         mov ds, ax         mov dx, offset string         mov ah, 9         int 21h         mov ax, 4c00h                 int 21h                ; 程序执行终止,返回DOS code    ends                ; 代码段结束         end start            ; 汇编结束,程序起始点为start 
DOS 系统功能调用 
在AH寄存器中设置系统功能调用号 
在指定寄存器中设置入口参数 
调用指令 int 21h 执行功能调用 
根据出口参数分析功能调用情况 
 
子功能号 
功能 
入口参数 
出口参数 
 
 
AH=01H 
输入一个字符 
AL = 输入字符的ASCII码 
 
AH=02H 
输出一个字符 
DL = 输出字符的ASCII码 
 
AH=09H 
输出一个字符串 
DS:DX = 字符串地址 
 
AH=0AH 
输入一个字符串 
DS:DX = 缓冲区地址 
 
AH=0BH 
判断是否有键按下 
AL = 0,无;AL = FFH, 有 
 
AH=4CH 
程序执行终止 
AL = 返回代码 
 
数值表达式 
个人把常数理解为宏定义,在汇编过程中完成替换与计算,不占用实际存储空间。
 
指由运算符连接的各种常数所构成的表达式,会在汇编过程中得到结果。
运算符类型 
运算符号 
 
 
算术运算符 
+,-,*,/,MOD 
 
逻辑运算符 
and,or,xor,not 
 
移位运算符 
shl,shr 
 
关系运算符 
eq,ne,gt,lt,ge,le 
 
高低分离符 
high,low,highword,lowword 
 
变量定义格式 定义伪指令 伪指令有 db dw dd(以及不常用的df dq dt)
初值表可以是直接由 , 分隔的参数,也可以由 dup 定义重复参数:
定位伪指令 org 参数,使其后面的数据或指令从参数指定地址开始。
1 2 org 100h                ; 从100h处开始安排数据或程序 org $+10                ; 使偏移地址+10 
even 参数,使其后面的数据或指令从偶地址开始。
若原地址为偶地址,则不变,否则将地址指针+1。
align n 参数,使其后面的数据或指令从 n 的整数倍开始。
处理类似 even。
这三个指令都可以在代码段使用,用于指定随后指令的偏移地址。
 
地址操作符 1 2 3 4 []                    ; 表示将括起来的表达式作为存储器地址指针 $                    ; 表示当前偏移地址 offset 名字/标号      ; 返回名字或标号的偏移地址 seg 名字/标号          ; 返回名字或标号的段地址 
类型操作符 1 2 3 类型名 ptr 名字/标号        ; 使名字或标号具有指定类型 this 类型名               ; 创建采用当前地址,但为指定类型的操作数 type 名字/标号               ; 返回一个字量数值,表明名字或标号的类型 
逻辑控制篇 分支结构 1 2 3 4 5 6 if (condition){     } else {     } 
在汇编中可以用如下结构实现:
1 2 3 4 5 6 7 8     cmp ..., ...     jcc satisfied     ; action2     jmp continue; satisfied:     ; action1 continue:     ... 
例:判断方程 $ax^2+bx+c=0$ 是否有实根,若有实根,将tag置1,否则置0.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 .model small .stack .data     _a db ?      _b db ?     _c db ?     tag db ? .code .startup     mov al, _b     imul al     mov bx, ax      ; 计算b^2放入bx中     mov al, _a     imul _c     mov cx, 4     imul cx         ; 计算4ac放入ax中     cmp bx, ax     jge yes     mov tag, 0     jmp done yes:     mov tag, 1 done: .exit 0 end 
循环结构 计数控制循环 
例:计算1~100数字和,将结果存入字变量sum中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 .model small .stack .data     sum dw ? .code .startup     xor ax, ax     mov cx, 100 again:     add ax, cx        ; 从100, 99, ..., 1 倒序相加      loop again     mov sum, ax .exit 0 end 
例:确定字变量wordX中1的最低位数(0~15),并将结果存于变量byteY中,若wordX没有为1的位,将-1存入byteY中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 .model small .stack .data     wordx dw 56     bytey db ? .code .startup     mov ax, wordx     mov cx, 16     mov dl, -1 again:     inc dl     test ax, 1     ror ax, 1     loope again     ; 运算结果为0, 即ax最低位非1, 继续循环     je notfound     mov bytey, dl     jmp done notfound:     mov bytey, -1 done: .exit 0 end 
条件控制循环 
例:将一个字符串中的所有大写字母改为小写字母,该字符串以 0 结尾
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 .model small .stack .data     string db 'Hello, Everybody!', 0 .code .startup          mov bx, offset string  again:     mov al, [bx]     or al, al     jz done     cmp al, 'A'     jb next     cmp al, 'Z'     ja next     or al, 20h     mov [bx], al next:     inc bx     jmp again done: .exit 0 end 
多重循环 
例:冒泡排序将长度已知的数组升序排序。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 .model small .stack .data     array db 56h, 23h, 37h, 78h, 0ffh, 0, 12h     count equ ($ - array) / type array .code .startup     mov cx, count                dec cx                  ; cx为外层循环次数 outlp:     mov dx, cx              ; dx为内层循环次数     mov bx, offset array    ; bx获取偏移地址 inlp:     mov al, [bx]     cmp al, [bx + 1]     jna next                ; 不大于就跳过,实现每次将最大的数放在队尾     xchg al, [bx + 1]     mov [bx], al next:     inc bx     dec dx     jnz inlp     loop outlp .exit 0 end 
子程序设计 1 2 3 过程名 proc[near\far]     过程体 过程名 endp 
例:实现回车、换行功能的子程序。
1 2 3 4 5 6 7 8 9 10 11 12 13 dpcref proc     push ax     push dx     mov dl, 0hd     mov ah, 2     int 21h     mov dl, 0ah     mov ah, 2     int 21h     pop dx     pop ax     ret dpcref endp 
参数传递的实现:
用寄存器传递参数:将参数存于约定的寄存器中。 
用变量传递参数:直接用同一个变量名访问传递的参数。 
用堆栈传递参数:主程序将入口参数压入堆栈,子程序弹出数据。 
 
 
(堆栈传递参数)递归实现阶乘计算:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 .model small .stack .data     n dw 3     result dw ? .code .startup     mov bx, n     push bx     call fact     pop result .exit 0 fact proc     push ax     push bp     mov bp, sp     mov ax, [bp+6]     cmp ax, 0     jne fact1     inc ax     jmp fact2 fact1:     dec ax     push ax     call fact     pop ax     mul word ptr[bp+6] fact2:     mov [bp+6], ax     pop bp     pop ax     ret fact endp end