625210M M DD MOV AX 625 MOV BX
• ~例:实现 625*210→M。 • M DD ? • MOV AX, 625 • MOV BX, 210 • MUL BX ; 16位乘法:结果为 32位 • MOV M , AX • MOV M+2, DX
DATA SEGMENT USE 16 VARX DW 6 VARY DW 7 RESULT DW ? DATA ENDS CODE SEGMENT USE 16 ASSUME CS: CODE, DS: DATA START: MOV AX, DATA MOV DS, AX MOV DX, VARX ADD DX, VARY MOV CL, 3 SAL DX, CL SUB DX, VARX SAR DX, 1 MOV RESULT, DX MOV AH, 4 CH INT 21 H CODE ENDS END START Z=((X+Y)*8 -X)/2 SAL 示意图
• • JS LOOP 1 ; SF=1, 小于0转移 JZ LOOP 2 ; ZF=0, 等于0转移 MOV BETA, 0 FFH ; 大于0 JMP LOOP 3 ; 能否省略? • LOOP 1: MOV BETA+2, 0 FFH • JMP LOOP 3 ; 能否省略? • LOOP 2: MOV BETA+1, 0 FFH • LOOP 3: …… • END START
• X DB ? • Y DB ? • • ; 自变量X ; 函数值Y MOV AL, 0 ; 同时假设Y=0 CMP X, AL JG BIG ; X大于0 JZ SAV ; X等于0 、Y=0 MOV AL, 0 FFH ; X小于0、Y= 1 JMP SHORT SAV BIG: MOV AL, 1 ; Y=1 SAV: MOV Y, AL ; 保存结果
• • • • CODE SEGMENT USE 16 ASSUME CS: CODE,DS: DATA BEG: MOV AX,DATA MOV DS,AX MOV DX,OFFSET MESG 1; 预设一种结果 CMP NUMBER,N 1 ; 无需PTR JNC NEXT ; X>=N 1 MOV DX,OFFSET MESG 2 ; X<N 1 JMP DISP NEXT: CMP NUMBER,N 2+1 ; X>=N 1 JC DISP ; N 1<=X<=N 2 ; 如果上一条指令N 2+1改用N 2则JC应改为JBE MOV DX,OFFSET MESG 3 ; X>N 2
• • • . 486 DATA SEGMENT USE 16 JUMP DB 3 //dw, 占两个单元,存储的标号(偏移地址放进去), 一 般是数 //间接转移 BX or DS: [] TAB DW P 000 ; P 000是标号 DW P 001 . . . DW P 255 DATA ENDS • CODE SEGMENT USE 16 • ASSUME CS: CODE,DS: DATA
• • • CODE SEGMENT ASSUME CS: CODE,DS: DATA START: MOV AX,DATA MOV DS,AX MOV DI,OFFSET TABLE ; 逐个读取分数 MOV SI,OFFSET ADDR NEXT: MOV AL,[DI] ; 逐个读取分数 CMP AL,'*' JE OVER INC DI ; 准备读取下一个数据
• • • CMP AL,60 JAE NEXT MOV AL,0 ; 当分数低于60时,AL直接置 0 MOV AH,0 ; AL/10 -5 MOV BL,10 DIV BL SUB AL,5 ; AL介于1~ 4 MOV BL,AL MOV BH,0 ; BX介于0~ 4 ADD BX,BX ; 乘以 2 JMP [SI+BX]
• • • S 59: INC SORT JMP NEXT S 69: INC SORT+1 JMP NEXT S 79: INC SORT+2 JMP NEXT S 89: INC SORT+3 JMP NEXT S 99: INC SORT+4 JMP NEXT
• • • • OVER: MOV CX, 5 ;显示结果 MOV SI, OFFSET SORT 1 DISP: MOV AH, 2 MOV DL, 13 INT 21 H MOV AH, 2 MOV DL, 10 INT 21 H INC SI MOV DL, [SI] ADD DL, 30 H MOV AH, 2 INT 21 H LOOP DISP • • MOV AH, 4 CH INT 21 H CODE ENDS END START
[解法 1]循环次数已知 • DATA SEGMENT USE 16 • BUF DB 'QWERTYUIOP 123' • COUNT EQU $ BUF • ; 统计字节个数、即循环次数 • MAX DB ‘MAX=’,? ,0 DH, 0 AH, ‘$’ • DATA ENDS • CODE SEGMENT USE 16 • ASSUME CS: CODE,DS: DATA BEG: MOV AX,DATA • MOV DS,AX
• • • MOV AL,0 ; 假设最大数 0送AL LEA BX,BUF MOV CX,COUNT LAST: CMP [BX],AL JB NEXT MOV AL,[BX] ; 大数 NEXT: INC BX //CX会自动减一 LOOP LAST • //唯一一种省略ds的情 况 • MOV MAX+4,AL • MOV AH,9 • LEA DX,MAX • INT 21 H • • MOV AH,4 CH INT 21 H CODE ENDS END BEG
• • • CODE SEGMENT USE 16 ASSUME CS: CODE,DS: DATA BEG: MOV AX,DATA MOV DS,AX MOV AL,0 ; 最小无符号数 0送AL LEA BX,BUF //不能省,必须指明长度 LAST: CMP BYTE PTR [BX], 1 JE DISP ; 结束 CMP [BX],AL JC NEXT MOV AL,[BX]
• NEXT: INC BX • JMP LAST • • DISP: MOV MAX+4,AL MOV AH,9 MOV DX,OFFSET MAX INT 21 H MOV AH,4 CH INT 21 H CODE ENDS END BEG
• INC BL ; 计数器加 1 • LOOP 2: INC SI ; 修改指针 • LOOP 1 ; CX≠ 0, 继续循 环 • MOV NUMBER, BL • END START
• ~例:内存缓冲区从BUF+1开始存有若干个单字节的 有符号数,其个数放在BUF单元,要求找出最大数 送到MAX单元,最小数送到MIN单元。 • DATA SEGMENT USE 16 • BUF DB 8, 34, 56, 1, 7 FH, 88, 200, 22, 80 H • MAX DB ? • MIN DB ? • DATA ENDS • • • CODE SEGMENT USE 16 ASSUME CS: CODE, DS: DATA BEG: MOV AX, DATA MOV DS, AX
• • • MOV CH, 0 MOV CL, BUF MOV AL, BUF+1 MOV MAX, AL MOV MIN, AL DEC CX • MOV BX, OFFSET BUF+2 • LAST: MOV AL, [BX] • CMP AL, MAX • JG GREAT • • • • CMP AL, MIN JL LESS JMP NEXT GREAT: MOV MAX, AL JMP NEXT LESS: MOV MIN, AL NEXT: INC BX LOOP LAST MOV AH, 4 CH INT 21 H CODE ENDS END BEG
• ~例.在字型无序表中找出最大数和最小数,并分别 存入MAX和MIN单元。 • STACKSG SEGMENT STACK 'STK' • DW 32 DUP('S') • STACKSG ENDS • DATA SEGMENT • BUFFER DW 500, 30, 56, 77, 999, 67, 433, 5675, 0, 9999, 3455, 6578, 32766, 8, 0, 32560, 45, 889, 5665, 09 ; 无序表 • CN DW ($ BUFFER)/2 ; 元素个数 • MAX DW ? ; 存放最大数单元 • MIN DW ? ; 存放最小数单元 • DATA ENDS
• • • • CODE SEGMENT MAIN PROC FAR ASSUME CS: CODE, DS: DATA PUSH DS XOR AX, AX PUSH AX MOV AX, DATA MOV DS, AX LEA SI, BUFFER ; 初始化地址指针 MOV CX, CN ; 元素个数 MOV AX, [SI] ; 取第一数 MOV MAX, AX ; 初始化最大数 MOV MIN, AX ; 初始化最小数 DEC CX ; 循环次数减 1
• RET • MAIN ENDP • CODE ENDS • END MAIN
• 2.调用程序和子程序在不同段的程序结构(SUB 2既被段间调用又被段内 调用, 必须是FAR属性。CALL要显式说明是FAR属性) • CODE 1 MAIN • • • MAIN • CODE 1 SEGMENT PROC FAR CALL FAR PTR SUB 2 RET ENDP ENDS • CODE 2 • SUB 2 • • SUB 2 SEGMENT PROC FAR RET ENDP • SUB 3 • • • SUB 3 • CODE 2 • PROC CALL FAR PTR SUB 2 RET ENDP ENDS END MAIN
• CODE SEGMENT USE 16 • ASSUME CS: CODE,DS: DATA,SS: STACK_ • • BEG: MOV AX,DATA MOV DS,AX MOV SI,OFFSET NUM SI CALL COMPUTE ; BX中为 3个数之和
• CODE SEGMENT USE 16 • ASSUME CS: CODE,DS: DATA,SS: STACK_ • • BEG: MOV AX,DATA MOV DS,AX MOV SI,OFFSET NUM SI CALL COMPUTE ; BX中为 3个数之和 CALL DISP MOV AH,4 CH INT 21 H
; DISPLAY— ; 将BX中的数值以二进制 ASCII码显示到屏幕 DISP PROC NEAR • MOV CX,16 LAST: MOV DL,'0' • RCL BX,1 • JNC NEXT • MOV DL,'1' NEXT: MOV AH,2 • INT 21 H • LOOP LAST • RET • DISP ENDP • CODE ENDS • END BEG
• [解法 2]主程序通过堆栈传递参数给子程序 COMPUTE • • • DATA SEGMENT USE 16 NUM DW 1122 H ; 加数N 1 DW 3344 H ; 加数N 2 DW 5566 H ; 加数N 3 DATA ENDS • STACK_ SEGMENT STACK USE 16 • DB 100 H DUP(? ) • STACK_ ENDS
• • • CODE SEGMENT USE 16 ASSUME CS: CODE,DS: DATA,SS: STACK_ BEG: MOV AX,DATA MOV DS,AX MOV SI,OFFSET NUM ; 图示:SP的变化: 初始为SP 0 PUSH WORD PTR [SI+0] ; SP 0 2 、 1122 H入栈 PUSH WORD PTR [SI+2] ; SP 0 4 、 3344 H入栈 PUSH WORD PTR [SI+4] ; SP 0 6 、 5566 H入栈 CALL COMPUTE ; SP 0 8(段内) 、断点入栈 XYZ:
• • • CODE SEGMENT USE 16 ASSUME CS: CODE,DS: DATA,SS: STACK_ BEG: MOV AX,DATA MOV DS,AX MOV SI,OFFSET NUM ; 图示:SP的变化: 初始为SP 0 PUSH WORD PTR [SI+0] ; SP 0 2 、 1122 H入栈 PUSH WORD PTR [SI+2] ; SP 0 4 、 3344 H入栈 PUSH WORD PTR [SI+4] ; SP 0 6 、 5566 H入栈 CALL COMPUTE ; SP 0 8(段内) 、断点入栈 XYZ: CALL DISP MOV AH,4 CH INT 21 H
• • • ; DISPLAY— DISP PROC NEAR MOV CX,16 LAST: MOV DL,'0' RCL BX,1 JNC NEXT MOV DL,'1' NEXT: MOV AH,2 INT 21 H LOOP LAST RET DISP ENDP • CODE ENDS • END BEG
• MOV AH,4 CH • INT 21 H
• • • • ; COMPUTE ;参数在代码段(CS) COMPUTE PROC NEAR MOV BP,SP MOV SI,[BP+0] ; SI←栈顶OFFSET NUM MOV BX,0 ; 初始和为 0 ADD BX,CS: [SI+0] ; 加数N 1; CS不能省略 ; 理解:加数可以用CS: [NUM]寻址 ADD BX,CS: [SI+2] ; 加数N 2 ADD BX,CS: [SI+4] ; 加数N 3 POP AX ; 将栈顶元素OFFSET NUM值抛弃 MOV AX,OFFSET XYZ PUSH AX ; 把真正的断点OFFSET XYZ压入堆栈 RET ; 弹出断点→IP,返回主程序XYZ处 COMPUTE ENDP
• ; DISPLAY— • DISP PROC NEAR ; 显示BX中各个二进制位 • MOV CX,16 LAST: MOV DL,'0' • RCL BX,1 • JNC NEXT • MOV DL,'1' NEXT: MOV AH,2 • INT 21 H • LOOP LAST • RET • DISP ENDP • CODE ENDS • END BEG
• • STACK SEGMENT STACK DW 256 DUP(? ) TOP LABEL WORD ; TOP为字地址 STACK ENDS • • • CODE SEGMENT ASSUME CS: CODE, DS: DATA, SS: STACK MAIN: MOV AX, DATA MOV DS, AX • MOV AX, STACK • MOV SS, AX • MOV SP, OFFSET TOP
• MAX_MIN PROC NEAR • • • PUSH AX PUSH BX PUSH CX PUSH SI MOV AX, [SI] ; 最大数 MOV BX, AX ; 最小数 LOPX: ADD SI , 2 CMP [SI] , AX ; 与较大的AX比较 • JC MINU • ; 如果小于较大的AX, 则继续与较小的BX比较 • JZ NEXT;等于AX • MOV AX, [SI]; 大于AX • JMP NEXT; 能否省略 • MINU: CMP [SI], BX • JNC NEXT ; 大于BX • MOV BX, [SI]; 小于BX • NEXT: LOOP LOPX
• • • MOV MAX, AX ; 保存较大数 MOV MIN, BX ; 保存较小数 POP SI POP CX POP BX POP AX RET MAX_MIN ENDP CODE ENDS END MAIN
• • • CODE 1 SEGMENT MAIN PROC FAR ASSUME CS: CODE 1, DS: DATA PUSH DS XOR AX, AX PUSH AX MOV AX, DATA MOV DS, AX CALL FAR PTR ARY_SUM RET MAIN ENDP CODE 1 ENDS
• • • CODE 2 SEGMENT ASSUME CS: CODE 2 ARY_SUM PROC FAR; 数组求和子程序 PUSH AX ; 保存寄存器 PUSH CX PUSH SI LEA SI, ARY ; 取数组起始地址 MOV CX, COUNT ; 取元素个数 XOR AX, AX ; 清0累加器
• • • NEXT: ADD AX, [SI] ADD SI, TYPE ARY LOOP NEXT MOV SUM, AX POP SI POP CX POP AX RET ARY_SUM ENDP CODE 2 ENDS END MAIN ; 累加和 ; 修改地址指针 ; 存和 ; 恢复寄存器
• STACKSG SEGMENT STACK 'STK' • DW 32 DUP('S') • STACKSG ENDS • • • DATA SEGMENT ARY DW 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ; 数组1 COUNT DW ($ ARY)/2 ; 数组1的元素个数 SUM DW ? ; 数组1的和地址 NUM DW 10, 20, 30, 40, 50 ; 数组2 CT DW ($ NUM)/2 ; 数组2的元素个数 TOTAL DW ? ; 数组2的和地址 TABLE DW 3 DUP(? ) ; 地址表 DATA ENDS
• • • • CODE 1 SEGMENT MAIN PROC FAR ASSUME CS: CODE 1, DS: DATA PUSH DS XOR AX, AX PUSH AX MOV AX, DATA MOV DS, AX ; 构造数组1的地址表 MOV TABLE, OFFSET ARY MOV TABLE+2, OFFSET COUNT MOV TABLE+4, OFFSET SUM LEA BX, TABLE ; 传递地址表首地址 CALL FAR PTR ARY_SUM
• • • ; 构造数组2的地址表 MOV TABLE, OFFSET NUM MOV TABLE+2, OFFSET CT MOV TABLE+4, OFFSET TOTAL LEA BX, TABLE ; 传递地址表的首地址 CALL FAR PTR ARY_SUM ; 段间调用调用数组求和子程序 RET MAIN ENDP CODE 1 ENDS
• • • CODE 2 SEGMENT ASSUME CS: CODE 2 ARY_SUM PROC FAR; 数组求和子程序 PUSH AX ; 保存寄存器 PUSH CX PUSH SI PUSH DI MOV SI, [BX] ; 取数组起始地址 MOV DI, [BX+2]; 取元素个数地址 MOV CX, [DI] ; 取元素个数 MOV DI, [BX+4] ; 取结果地址 XOR AX, AX ; 清0累加器
• • • NEXT: ADD AX, [SI] ADD SI, TYPE ARY LOOP NEXT MOV [DI], AX POP DI POP SI POP CX POP AX RET ARY_SUM ENDP CODE 2 ENDS END MAIN ; 累加和 ; 修改地址指针 ; 存和 ; 恢复寄存器
• 例.完成数组求和功能,求和由子程序实现, 要求通过堆栈传递参数地址。 • STACKSG SEGMENT STACK ‘STK’ • DW 16 DUP(?) • STACKSG ENDS • • • DATA SEGMENT ARY DW 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 COUNT DW ($ ARY)/2 SUM DW ? DATA ENDS
• • CODE 1 SEGMENT MAIN PROC FAR ASSUME CS: CODE 1, DS: DATA PUSH DS ; ⑴ XOR AX, AX PUSH AX ; ⑵ MOV AX, DATA MOV DS, AX
• • • LEA BX, ARY PUSH BX ; ⑶压入数组起始地址 LEA BX, COUNT PUSH BX ; ⑷压入元素个数地址 LEA BX, SUM PUSH BX ; ⑸压入和地址 CALL FAR PTR ARY_SUM ; ⑹调用求和子程序 RET ; ⒅ MAIN ENDP CODE 1 ENDS
• • • CODE 2 SEGMENT ASSUME CS: CODE 2 ARY_SUM PROC FAR; 数组求和子程序 PUSH BP ; ⑺保存BP值 MOV BP, SP ; BP是堆栈数据的地址指针 PUSH AX ; ⑻保存寄存器内容 PUSH CX ; ⑼ PUSH SI ; ⑽ PUSH DI ; ⑾
• • • POP DI ; ⑿恢复寄存器内容 POP SI ; ⒀ POP CX ; ⒁ POP AX ; ⒂ POP BP ; ⒃ RET 6 ; ⒄返回并调整SP指针 ARY_SUM ENDP CODE 2 ENDS END MAIN
• STACKSG SEGMENT STACK 'STK' • DW 16 DUP('S') • STACKSG ENDS • • • DATA SEGMENT ARY DW 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 COUNT DW ($ ARY)/2 SUM DW ? DATA ENDS
• • CODE 1 SEGMENT MAIN PROC FAR ASSUME CS: CODE 1, DS: DATA PUSH DS XOR AX, AX PUSH AX MOV AX, DATA MOV DS, AX
• • • LEA BX, ARY PUSH BX ; 压入数组起始地址 LEA BX, COUNT PUSH BX ; 压入元素个数地址 LEA BX, SUM PUSH BX ; 压入和地址 CALL FAR PTR ARY_SUM RET MAIN ENDP CODE 1 ENDS
• CODE 2 SEGMENT ASSUME CS: CODE 2 • STACK_STRC STRUC ; 定义结构 • SAVE_BP DW ? • SAVE_CS_IP DW 2 DUP(? ) • SUM_ADDR DW ? • COUNT_ADDR DW ? • ARY_ADDR DW ? • STACK_STRC ENDS
• • • ARY_SUM PROC FAR; 数组求和子程序 PUSH BP ; 保存BP值 MOV BP, SP PUSH AX PUSH CX PUSH SI PUSH DI MOV SI, [BP]. ARY_ADDR; 数组始地址 MOV DI, [BP]. COUNT_ADDR MOV CX, [DI]
• • • • MOV DI, [BP]. SUM_ADDR; 得到和地址 XOR AX, AX NEXT: ADD AX, [SI] ; 累加 ADD SI, TYPE ARY ; 修改地址指针 LOOP NEXT MOV [DI], AX ; 存和 POP DI POP SI POP CX POP AX POP BP RET 6 ; 返回并调整SP指针 ARY_SUM ENDP CODE 2 ENDS END MAIN
• • • • CODE 1 SEGMENT ASSUME CS: CODE 1 SUB 1 PROC FAR PUSH CX DEC CX CMP CX, 0 JE NEXT CALL SUB 1 NEXT: POP CX ; DEC之前的CX值 MUL CL ; 8位操作数的乘积存于AX ; /* NEXT: INC CL MUL CL POP CX */ RET SUB 1 ENDP CODE 1 ENDS
• • CODE SEGMENT ASSUME CS: CODE, DS: DATA, SS: STACK 1 START: MOV AX, DATA MOV DS, AX MOV AX, 1 MOV CX, N CALL SUB 1 MOV RESULE, AX • • MOV AH, 4 CH INT 21 H CODE ENDS END START
• END
- Slides: 122