rotate printit mov ch 4 mov cl 4

  • Slides: 71
Download presentation

rotate: printit: mov ch, 4 mov cl, 4 rol bx, cl mov al, bl

rotate: printit: mov ch, 4 mov cl, 4 rol bx, cl mov al, bl and al, 0 fh add al, 30 h cmp al, 3 ah jl printit add al, 7 h mov dl, al mov ah, 2 int 21 h dec ch jnz rotate ; ’ 0’-’ 9’ ASCII 30 H-39 H ; ’A’-’F’ ASCII 41 H-46 H 4

例2. 将正数n插入一个已整序的字数组的正确位置。 x dw ? array_head dw 3, 5, 15, 23, 37, 49, 52,

例2. 将正数n插入一个已整序的字数组的正确位置。 x dw ? array_head dw 3, 5, 15, 23, 37, 49, 52, 65, 78, 99 array_end dw 105 x -1 n dw 32 3 mov ax, n 5 mov array_head-2, 0 ffffh 15 mov si, 0 23 37 compare: 49 cmp array_end[si], ax 52 jle insert 65 mov bx, array_end[si] 78 mov array_end[si+2], bx 99 sub si, 2 105 jmp short compare n 32 insert: 6 mov array_end[si+2], ax

例3 将首地址为A的字数组从小到大排序(气泡算法,多重循环) A dw 32, 85, 16, 15, 8 P 119 比 较 遍

例3 将首地址为A的字数组从小到大排序(气泡算法,多重循环) A dw 32, 85, 16, 15, 8 P 119 比 较 遍 数 序号 地址 数 1 2 3 4 1 A 32 2 A+2 85 3 A+4 16 4 A+6 15 5 A+8 8 32 16 15 8 85 16 15 8 32 85 15 8 16 32 85 8 15 16 32 85 7

loop 1: loop 2: continue: mov cx, 10 dec cx mov di, cx mov

loop 1: loop 2: continue: mov cx, 10 dec cx mov di, cx mov bx, 0 mov cmp jle xchg mov ax, A[bx] ax, A[bx+2] continue ax, A[bx+2] A[bx], ax add loop mov loop bx, 2 loop 2 cx, di loop 1 8

(1)逻辑尺控制 (2)条件控制 。。。。。。 ? case 1 case 2 case n ? case 1 case

(1)逻辑尺控制 (2)条件控制 。。。。。。 ? case 1 case 2 case n ? case 1 case 2 case 3 (3)地址跳跃表 TABLE DW ONE, TWO, THREE JMP TABLE[SI] … 1000 ONE: … 2000 TWO: … 3000 THREE: … 10

x y z logic_rule dw x 1, x 2, x 3, x 4, x

x y z logic_rule dw x 1, x 2, x 3, x 4, x 5, x 6, x 7, x 8, x 9, x 10 dw y 1, y 2, y 3, y 4, y 5, y 6, y 7, y 8, y 9, y 10 dw z 1, z 2, z 3, z 4, z 5, z 6, z 7, z 8, z 9, z 10 dw 00 dch …… mov bx, 0 mov cx, 10 mov dx, logic_rule next: mov ax, x[bx] shr dx, 1 jc subtract add ax, y[bx] jmp short result ; 向前引用 subtract: sub ax, y[bx] result: mov z[bx], ax add bx, 2 loop next 12

例2. 根据AL寄存器中哪一位为 1(从低位到高位)把程序 转移到 8个不同的程序分支去 。(寄存器间接寻址) branch_table dw routine 1 dw routine 2 dw

例2. 根据AL寄存器中哪一位为 1(从低位到高位)把程序 转移到 8个不同的程序分支去 。(寄存器间接寻址) branch_table dw routine 1 dw routine 2 dw routine 3 dw routine 4 dw routine 5 dw routine 6 dw routine 7 dw routine 8 cmp je lea L: shr jnc jmp     add 1: add jmp continue: routine 1: routine 2: …… al, 0 continue bx, branch_table al, 1 ; 逻辑右移 add 1 word ptr [bx] ; 段内间接转移 bx, 2 L …… …… …… 13

保存与恢复寄存器 subt proc far push. . . pop pop ax bx cx dx dx

保存与恢复寄存器 subt proc far push. . . pop pop ax bx cx dx dx cx bx ax ret subt endp 15

例3. 十进制到十六进制的转换程序(通过寄存器传送变量) Decihex segment assume cs: decihex main proc push sub push repeat: main

例3. 十进制到十六进制的转换程序(通过寄存器传送变量) Decihex segment assume cs: decihex main proc push sub push repeat: main call jmp ret endp ; 10 16 far ds ax, ax ax decibin ; 10 2 crlf binihex ; 2 16 crlf repeat 19

Decibin newchar: exit: decibin proc mov int sub jl cmp jg cbw xchg mov

Decibin newchar: exit: decibin proc mov int sub jl cmp jg cbw xchg mov mul xchg add jmp ret endp near ; 10 2 bx, 0 ah, 1 21 h al, 30 h exit ; <0退出 al, 9 d exit ; >9退出 ax, bx cx, 10 d cx ax, bx bx, ax newchar 20

binihex proc near mov ch, 4 rotate: mov cl, 4 rol bx, cl mov

binihex proc near mov ch, 4 rotate: mov cl, 4 rol bx, cl mov al, bl and al, 0 fh add al, 30 h cmp al, 3 ah jl printit add al, 7 h printit: mov dl, al mov ah, 2 int 21 h dec ch jnz rotate ret binihex endp ; 2 16 ; ‘A’~’F’ 21

crlf proc mov mov int ret endp near dl, 0 dh ah, 2 21

crlf proc mov mov int ret endp near dl, 0 dh ah, 2 21 h dl, 0 ah ah, 2 21 h decihex ends end main 22

例4. 累加数组中的元素(直接访问变量) data segment ary dw 1, 2, 3, 4, 5, 6, 7, 8,

例4. 累加数组中的元素(直接访问变量) data segment ary dw 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 count dw 10 sum dw ? data ends code segment main proc far assume cs: code, ds: data start: push ds sub ax, ax push ax mov ax, data mov ds, ax call near ptr proadd ret main endp 23

proadd proc push next: lea mov xor add loop mov near ax cx si

proadd proc push next: lea mov xor add loop mov near ax cx si si, ary cx, count ax, ax ax, [si] si, 2 next sum, ax pop si pop cx pop ax ret proadd endp code ends end start 24

如果数据段定义如下: data ary count sum segment dw 1, 2, 3, 4, 5, 6, 7,

如果数据段定义如下: data ary count sum segment dw 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 dw ? ary 1 dw 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 count 1 dw 10 sum 1 dw ? data ends *如果直接访问内存变量,那么累加数组ary和数组ary 1中 的元素不能用同一个子程序proadd 25

例5. 累加数组中的元素(通过地址表传送变量地址) data ary count sum table data code main assume start: segment dw

例5. 累加数组中的元素(通过地址表传送变量地址) data ary count sum table data code main assume start: segment dw 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 dw 10 dw ? dw 3 dup (? ) ; 地址表 ends segment proc far cs: code, ds: data push ds sub ax, ax push ax mov ax, data mov ds, ax mov mov main call ret endp table, table+2, table+4, bx, proadd offset ary count sum table 26

proadd proc push next: mov mov xor add loop mov near ax cx si

proadd proc push next: mov mov xor add loop mov near ax cx si di si, [bx] di, [bx+2] cx, [di] di, [bx+4] ax, ax ax, [si] si, 2 next [di], ax pop di pop si pop cx pop ax ret proadd endp code ends end start ary 10 20 30 40 0000(si) 0002 50 60 70 80 90 100 count 10 0014 sum ? 0016 (di) table 0000 0018 (bx) 0014 0016 27

例6. 累加数组中的元素(通过堆栈传送变量地址) data segment ary dw 10, 20, 30, 40, 50, 60, 70, 80,

例6. 累加数组中的元素(通过堆栈传送变量地址) data segment ary dw 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 count dw 10 sum dw ? data ends stack segment dw 100 dup (? ) tos label word stack ends 28

code 1 segment main proc far assume cs: code 1, ds: data, ss: stack

code 1 segment main proc far assume cs: code 1, ds: data, ss: stack start: mov ax, stack mov ss, ax mov sp, offset tos push ds sub ax, ax push ax mov ax, data mov ds, ax mov push bx, offset ary bx bx, offset count bx bx, offset sum bx call far ptr proadd ret main endp code 1 ends 29

code 2 segment assume cs: code 2 proadd proc far push bp mov bp,

code 2 segment assume cs: code 2 proadd proc far push bp mov bp, sp push ax cx si di mov mov si, [bp+0 ah] di, [bp+8] cx, [di] di, [bp+6] xor next: add loop mov pop pop ax, ax ax, [si] si, 2 next [di], ax di si cx ax (sp) (di) (si) (cx) (ax) (bp) (ip) (cs) pop bp (bp)+6 0016 (bp)+8 0014 ret 6 (bp)+0 a proadd endp 0000 0 code 2 ends (ds) end start 30

例8 十六进制到十进制的转换程序(通过寄存器传送变量) hexidec segment main start: repeat: main proc far assume cs: hexidec ;

例8 十六进制到十进制的转换程序(通过寄存器传送变量) hexidec segment main start: repeat: main proc far assume cs: hexidec ; 16 10 push ds sub ax, ax push ax call jmp ret endp hexibin crlf binidec crlf repeat ; 16 2 ; 2 10 31

hexibin proc near mov bx, 0 newchar: ; 16 2 mov ah, 1 int

hexibin proc near mov bx, 0 newchar: ; 16 2 mov ah, 1 int 21 h add_to: sub jl cmp jl sub cmp jl cmp jge al, 30 h exit al, 10 d add_to al, 27 h al, 0 ah exit al, 10 h exit ; ‘ a ’ ~ ‘ f ’ mov cl, 4 shl bx, cl mov ah, 0 add bx, ax jmp newchar exit: ret hexibin endp 32

binidec proc near ; 2 10 mov cx, 10000 d call dec_div mov cx,

binidec proc near ; 2 10 mov cx, 10000 d call dec_div mov cx, 100 d call dec_div mov cx, 1 d call dec_div ret dec_div proc near mov ax, bx mov dx, 0 div cx mov bx, dx mov add mov int dl, al dl, 30 h ah, 2 21 h ret dec_div endp binidec endp 33

crlf proc near mov dl, 0 ah mov ah, 2 int 21 h mov

crlf proc near mov dl, 0 ah mov ah, 2 int 21 h mov dl, 0 dh mov ah, 2 int 21 h ret endp hexidec ends end start 34

设备控制寄存器 端口 61 H 1 0 1 / 0 0 2号定时器门控 控制其它外部设备 与 门

设备控制寄存器 端口 61 H 1 0 1 / 0 0 2号定时器门控 控制其它外部设备 与 门 放大器 例1. Sound程序 mov dx, 6000 ; 声音频率 in al, 61 h and al, 11111100 b trig: xor al, 00000010 b out 61 h, al mov cx, 1000 ; 声音延迟 delay: loop delay dec dx jne trig P 137 37

例2. CPU要从3个设备轮流输入数据,设备1, 2, 3的状态寄存器 端口号分别用STAT 1, STAT 2, STAT 3表示,第 5位是输入 准备位。 INPUT: IN

例2. CPU要从3个设备轮流输入数据,设备1, 2, 3的状态寄存器 端口号分别用STAT 1, STAT 2, STAT 3表示,第 5位是输入 准备位。 INPUT: IN TEST JZ CALL DEV 2: IN TEST JZ CALL DEV 3: IN TEST JZ CALL NO_INPUT: …… AL, STAT 1 AL, 20 H ; 0010 0000 b DEV 2 FAR PTR PROC 1 AL, STAT 2 AL, 20 H DEV 3 FAR PTR PROC 2 AL, STAT 3 AL, 20 H NO_INPUT FAR PTR PROC 3 38

例1 用DOS功能调用存取中断向量 MOV AL, N MOV AH, 35 H INT 21 H ; 取原中断向量

例1 用DOS功能调用存取中断向量 MOV AL, N MOV AH, 35 H INT 21 H ; 取原中断向量 PUSH ES PUSH BX ; 保存原中断向量 PUSH DS MOV AX, SEG INTHAND MOV DS, AX MOV DX, OFFSET INTHAND MOV AL, N MOV AH, 25 H INT 21 H ; 设置新的中断向量 POP DS …… POP DX POP DS MOV AL, N MOV AH, 25 H INT 21 H ; 恢复原中断向量 RET ; INTHAND: …… IRET 43

例2. 编写一个中断处理程序,要求在主程序运行期间,每隔 10秒响铃一次,同时显示‘The bell is ring!’ P 147 dseg segment count dw 1 mess

例2. 编写一个中断处理程序,要求在主程序运行期间,每隔 10秒响铃一次,同时显示‘The bell is ring!’ P 147 dseg segment count dw 1 mess db 'The bell is ring!', 0 ah, 0 dh, '$' dseg ends cseg segment main proc far assume cs: cseg, ds: dseg, es: dseg start: push ds mov ax, ax push ax mov ax, dseg mov ds, ax 46

mov al, 1 ch mov ah, 35 h int 21 h push es push

mov al, 1 ch mov ah, 35 h int 21 h push es push bx push ds mov dx, offset ring mov ax, seg ring mov ds, ax mov al, 1 ch mov ah, 25 h int 21 h pop ds in al, 21 h and al, 11111110 b out 21 h, al sti ; 取原中断向量 ; 保存原中断向量 ; 设置新的中断向量 ; 设置中断屏蔽位, 允许定时器中断 ; 开中断 47

mov di, 2000 delay: mov si, 3000 P 148 delay 1: dec si jnz

mov di, 2000 delay: mov si, 3000 P 148 delay 1: dec si jnz delay 1 dec di jnz delay ; 主程序 作(期间每秒产生中断 18. 2次) pop dx pop ds mov al, 1 ch mov ah, 25 h int 21 h ret main endp ; 恢复原中断向量 48

ring proc push far ds ax cx dx mov ax, dseg mov ds, ax

ring proc push far ds ax cx dx mov ax, dseg mov ds, ax sti dec jnz count exit mov dx, offset mess mov ah, 09 int 21 h ; 开中断, 允许更高级的中断 ; 显示‘The bell is ring!’ 49

mov in and sound: xor out mov wait 1: loop dec jne mov exit:

mov in and sound: xor out mov wait 1: loop dec jne mov exit: cli pop pop iret ring endp cseg ends end dx, 100 al, 61 h al, 11111100 b P 149 al, 2 61 h, al cx, 140 h wait 1 dx sound count, 182 dx cx ax ds start ; 响铃 ; 关中断 50

dseg segment addr dw ? count dw ? buffer db 20 h dup ('

dseg segment addr dw ? count dw ? buffer db 20 h dup (' ') prompt db 'please input: ', 0 dh, 0 ah, '$' message db 'buffer full', 0 dh, 0 ah save_ip 9 dw ? save_cs 9 dw ? save_ipf dw ? save_csf dw ? dseg ;缓冲区指针 P 150 ends 52

cseg main segment proc far ;主程序 assume cs: cseg, ds: dseg start: push ds

cseg main segment proc far ;主程序 assume cs: cseg, ds: dseg start: push ds sub ax, ax push ax mov ax, dseg mov ds, ax lea ax, buffer mov addr, mov count, 0 ax 53

mov al, 09 mov ah, 35 h int 21 h ; 键盘 ; 取原中断向量

mov al, 09 mov ah, 35 h int 21 h ; 键盘 ; 取原中断向量 mov al, 0 fh mov ah, 35 h int 21 h ; 打印机 ; 取原中断向量 mov save_ip 9, bx save_cs 9, es ; 保存 mov dx, offset kbint push ds mov ax, seg mov ds, ax mov al, 09 mov ah, 25 h int 21 h pop ds kbint ; 设置新中断向量 mov save_ipf, bx save_csf, es ; 保存 cli mov dx, offset prtint push ds mov ax, seg mov ds, ax mov al, 0 fh mov ah, 25 h int 21 h pop ds prtint ; 设置新中断向量 54

mov in al, 21 h and al, 0 fdh out 21 h, al mainp:

mov in al, 21 h and al, 0 fdh out 21 h, al mainp: mov ah, 9 lea dx, prompt int 21 h ; 显示提示信息 si, 30000 h mainp 1: ; 允许键盘中断 mov di, 20000 h dec si jnz mainp 1 dec di jnz mainp P 151 ; 延迟 sti 55

 push ds cli mov dx, save_ipf push ds mov ax, save_csf mov dx,

push ds cli mov dx, save_ipf push ds mov ax, save_csf mov dx, save_ip 9 mov ds, ax mov ax, save_cs 9 mov al, 0 fh mov ds, ax mov ah, 25 h int 21 h ; 恢复原打印机中断 mov al, 09 pop ds mov ah, 25 h int 21 h in and out al, 21 h al, 0 fdh 21 h, al ; 恢复原键盘中断 pop ; 允许键盘中断 ds sti P 152 main ret endp 56

 kbint push proc near ax bx in al, 60 h push ax in

kbint push proc near ax bx in al, 60 h push ax in al, 61 h mov or out ah, al al, 80 h 61 h, al ; 送键盘应答信号 xchg out ah, al 61 h, al ; 复位键盘 pop test jnz ax al, 80 h cont ; 通码时处理 通码:(60 h)7=0 断码:(60 h)7=1 mov bx, addr mov [bx], al call disp inc bx inc count mov addr, bx check: cmp count, 32 jb cont ; 判断是否溢出 in al, 21 h or al, 02 ; 屏蔽键盘中断 and al, 7 fh out 21 h, al ; 允许打印机中断 call intip cont: cli mov al, 20 h out 20 h, al ; 结束键盘中断 pop bx pop ax iret kbint endp 57

intip proc push near ax bx dx cli mov mov out bx, offset message

intip proc push near ax bx dx cli mov mov out bx, offset message addr, bx dx, 378 h al, 0 dh dx, al ; 输出回车 dx, 37 ah al, 1 dh ; 0001 1101 dx, al ; 送选通信号 jmp $+2 mov out al, 1 ch dx, al pop dx bx pop ax ret intip endp ; 展宽选通信号 ; 0001 1100 P 154 58

prtint proc near push ax push bx push dx mov mov out push mov

prtint proc near push ax push bx push dx mov mov out push mov out bx, al, dx, ax dx, al, dx, addr [bx] 378 h al jmp $+2 mov out pop al, 1 ch dx, al ax 37 ah 1 dh al inc bx mov addr, bx cmp al, 0 ah jnz return in al, 21 h or al, 80 h out 21 h, al ; 屏蔽打印机中断 return: mov al, 20 h out 20 h, al ; 结束打印机中断 pop dx pop bx pop ax iret prtint endp P 154 59

disp proc push mov nextb: rol push mov and or cmp jl add dispit:

disp proc push mov nextb: rol push mov and or cmp jl add dispit: mov int pop dec jnz mov int pop pop ret disp endp cseg near ax cx dx ch, 2 cl, 4 al, cl ax dl, al dl, 0 fh dl, 30 h dl, 3 ah dispit dl, 7 ah, 2 21 h ax ch nextb ah, 2 dl, ', ' 21 h dx cx ax ends end start ; 显示扫描码 P 155 60

例: 输入字符串到缓冲区STRING DATA SEGMENT MAXLEN DB 32 , 0, 32 DUP(? ) ACTLEN DB

例: 输入字符串到缓冲区STRING DATA SEGMENT MAXLEN DB 32 , 0, 32 DUP(? ) ACTLEN DB ? MAXLEN DB 32 , 33 DUP(? ) STRING DB 32 DUP(? ) DATA ENDS MAXLEN ; CODE ACTLEN SEGMENT … LEA DX, MAXLEN MOV AH, 0 AH INT 21 H … CODE STRING 32 5 68 H 61 H 70 H 79 H 0 DH ENDS END 64

(1) BIOS显示中断 INT 10 H (2) 功能号 AH=1, 2, 3, 5, 6, 7, 8,

(1) BIOS显示中断 INT 10 H (2) 功能号 AH=1, 2, 3, 5, 6, 7, 8, 9, 0 AH, 0 EH, 13 H (p. 158) (3) 例:屏幕初始化或上卷 (AH=6) (4) mov ah, 6 ; to scroll up screen (5) mov al, 0 ; blank screen (6) mov bh, 7 ; blank line (7) mov ch, 0 ; upper left row (8) mov cl, 0 ; upper left column (9) mov dh, 24 ; lower right row (10) mov dl, 79 ; lower right column (11) int 10 h ; call video BIOS (12) P 165 66

例: 在品红背景下,显示 5个浅绿色闪烁的星号。 MOV AH,09 MOV AL,’*’ MOV BH,0 MOV BL,0 DAH ; 1101

例: 在品红背景下,显示 5个浅绿色闪烁的星号。 MOV AH,09 MOV AL,’*’ MOV BH,0 MOV BL,0 DAH ; 1101 1010 (表 4. 10) MOV CX,05 INT 10 H 67

例: 在屏幕上以红底兰字显示字符串:“WORLD SCENERY”。 STRING DB ‘WORLD SCENERY’ LEN_TR EQU $-STRING MOV INT MOV MOV

例: 在屏幕上以红底兰字显示字符串:“WORLD SCENERY”。 STRING DB ‘WORLD SCENERY’ LEN_TR EQU $-STRING MOV INT MOV MOV INT ┇ AL,3 AH,0 ; 80× 25, 16色文本方式 10 H BP,SEG STRING ES,BP BP,OFFSET STRING CX,LEN_STR DX,0 BL,41 H ; 0100 0001 AL,0 AH,13 H 10 H 68

例: 打印字符串TEXT DB ‘Hello,everybody!’ COUNT EQU $-TEXT …… MOV CX,COUNT MOV CX, COUNT MOV

例: 打印字符串TEXT DB ‘Hello,everybody!’ COUNT EQU $-TEXT …… MOV CX,COUNT MOV CX, COUNT MOV BX,0 MOV BX, 0 NEXT: MOV AH,5 NEXT: MOV AH, 0 MOV DL,TEXT[BX] INT 21 H MOV DX, 0 INC BX LOOP NEXT MOV AL, TEXT[BX] INT 17 H INC BX LOOP NEXT 71