- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
;过程体 ;恢复寄存器:逆序弹出堆栈
;过程返回 ;过程结束
子程序例子
子程序上
ALdisp proc push ax push cx push dx push ax mov dl,al mov cl,4 shr dl,cl or dl,30h cmp dl,39h jbe aldisp1 add dl,7 7 aldisp1:mov ah,2 24 int 21h ;实现al内容的显示 ;过程中使用了AX、CX和DX
20
程序定义伪指令
过程名(子程序名)为符合语法的标识符。 NEAR 属性(段内近调用)的过程只能被相同代 码段的其他程序调用; FAR 属性(段间远调用)的过程可以被相同或不 同代码段的程序调用。 对简化段定义格式,在微型、小型和紧凑存储模式 下,过程的缺省属性为 near ;在中型、大型和巨 型存储模式下,过程的缺省属性为 far。对完整段 定义格式,过程的缺省属性为near。 用户可以在过程定义时用near或far改变缺省属性。
13
;处理程序1 ;处理程序2 ;处理程序3 ;处理程序4
3 循环程序设计
循环结构一般是根据某一条件判断为真或 假来确定是否重复执行循环体。 循环指令和转移指令可以实现循环控制。
循环指令LOOP:例6 循环指令LOOPE:例7 转移指令:例8
多重循环:例9
14
例6 计算1~100数字之和
… sum dw ? 循环次数固定 … xor ax,ax ;被加数AX清0 mov cx,100 again:add ax,cx ;从100,99,...,2,1倒序累加 loop again mov sum,ax ;将累加和送入指定单元 …
12
;提示输入数字 ;等待按键
;数字 < 1?
;数字 > 8?
;将ASCII码转换成数字
;等效于add ax,ax ;(段内)间接转移:IP←[table+bx]
例5 分支体
start2:mov ah,9 int 21h … disp1:mov dx,offset msg1 jmp start2 disp2:mov dx,offset msg2 jmp start2 disp3:mov dx,offset msg3 jmp start2 disp4:mov dx,offset msg4 jmp start2 ...
多分支:例5
6
例3
;计算X-Leabharlann 的绝对值 mov ax,X sub ax,Y jnc nonneg ;条件满足(X-Y > 0)? neg ax ;条件不满足,求补 nonneg: mov result,ax ;条件满足
7
例4
mov al,b imul al mov bx,ax mov al,a imul c mov cx,4 imul cx cmp bx,ax ;比较二者大小 jge yes ;条件满足? mov tag,0 ;第1分支体:条件不满足,tag←0 jmp done ;跳过第2个分支体 yes: mov tag,1 ;第2分支体:条件满足,tag←1 done: … ;退出 前一分支后要使用JMP指令,切记!
16
例7 … 确定wordX中1的最低位数
例8 大写字母改为小写字母
… mov bx,offset string again:mov al,[bx] ;取一个字符 or al,0 ;是否为结尾符0 jz done ;是,退出循环 cmp al,'A' ;是否为大写A~Z jb next 循环次数不定, cmp al,'Z' 利用标志退出。 ja next
Y
Y Y
fuction0 fuction1
AH=1 N
AH=2 N
fuction2
9
例5 利用入口地址表,形成多分支
Table db disp1, disp2, disp3, disp4, ...
地址表
分支1地址
分支2地址
...
数据段 程序段 分支体
操作
10
例5 数据段
... msg msg1 msg2 msg3 msg4 msg5 msg6 msg7 msg8 table db 'Input number(1~8):',0dh,0ah,'$' db 'Chapter 1 : Fundamentals of Assembly Language',0dh,0ah,'$' db 'Chapter 2 : 8086 Instruction Set',0dh,0ah,'$' db 'Chapter 3 : Statements of Assembly Language',0dh,0ah,'$' db 'Chapter 4 : Assembly Language Programming',0dh,0ah,'$' db 'Chapter 5 : 32-bit Instructions and Programming',0dh,0ah,'$' db 'Chapter 6 : Mixed Programming with C/C++',0dh,0ah,'$' db 'Chapter 7 : FP Instructions and Programming',0dh,0ah,'$' db 'Chapter 8 : MMX Instructions and Programming',0dh,0ah,'$' dw disp1,disp2,disp3,disp4,disp5,disp6,disp7,disp8 ;取得各个标号的偏移地址
;调用程序段结束
操作
26
子程序的参数传递
入口参数(输入参数):主程序 提供给 子程序 出口参数(输出参数):子程序 返回给 主程序
参数的形式:①
数据本身(传值) ② 数据的地址(传址)
传递的方法:①
例10
寄存器 ② 变量 ③ 堆栈
子程序计算数组元素的“校验和” 数组的逻辑地址(传址), 元素个数(传值); 求和结果(传值)。
入口参数: 出口参数: 27
用寄存器传递参数
把参数存于约定的寄存器中,可以传值,也可以传 址。 主程序对带有出口参数的寄存器不能保护和恢复 (主程序视具体情况进行保护)。 子程序对带有入口参数的寄存器可以保护,也可以 不保护;但最好一致。
15
mov ax,wordX ;测试目标送AX mov cx,16 ;循环计数器置初值 mov dl,-1 ;计位器置初值 again:inc dl test ax,1 ror ax,1 ;循环指令不影响ZF loope again ;CX≠0且ZF=1(测试位为0) ;继续循环 je notfound 最大循环次数固定, mov byteY,dl 满足条件退出。 jmp done notfound:mov byteY,-1 ;ZF=1,测试目标的16个位 ;均为0 done:…
25
;恢复原ax值到dx ;转换al的低4位
;显示
子程序应用
… mov bx,offset array mov cx,count displp:mov al,[bx] call ALdisp mov dl,',' mov ah,2 int 21h inc bx loop displp … end
;调用程序段开始 ;调用显示过程 ;显示一个逗号,以分隔两个数据
3
例2 64位数据左移8位
qvar dq 1234567887654321h
mov al,byte ptr qvar[6] mov byte ptr qvar[7],al mov al,byte ptr qvar[5] mov byte ptr qvar[6],al mov al,byte ptr qvar[4] mov byte ptr qvar[5],al mov al,byte ptr qvar[3] mov byte ptr qvar[4],al
18
4 子程序设计
把功能相对独立的程序段单独编写和调试,作 为一个相对独立的模块供程序使用,就形成子 程序。 子程序可以实现源程序的模块化,可以简化源 程序结构,可以提高编程效率。
子程序设计要利用过程定义伪指令
参数传递是子程序设计的重点和难点
子程序可以嵌套; 一定条件下,还可以递归和重入
第3章 汇编语言程序设计(续)
1 2 3 4 5 6 7
1
顺序程序设计 分支程序设计 循环程序设计 子程序设计 宏结构程序设计 模块化程序设计 输入输出程序设计
1 顺序程序设计
顺序程序完全按指令书写的前后顺序执行 每一条指令,是最基本、最常见的程序结 构。 例1
例2
2
例1 w=x+y+z
data segment start:mov ax,data X dw 5 mov ds,ax Y dw 6 mov ax,X Z dw 7 add ax,Y W dw ? adc ax,Z data ends mov W,ax code segment mov ax,4c00h int 21h Assume cs:code, ds:data code ends end start
34 56 78 87 65 43 21 00h
移位后
12 34 56 78 87 65 43 21h
4
图示
2 分支程序设计
分支程序根据条件是真或假决定执行与否。 判断的条件是各种指令,如 CMP、 TEST 等执行后形成的状态标志。 转移指令Jcc和JMP可以实现分支控制。