汇编 输入输出指令
輸入輸出指令用來(lái)完成I/O端口與累加器之間的數(shù)據(jù)傳送,指令中給出I/O端口的地址值。當(dāng)執(zhí)行輸入指令時(shí),把指定端口中的數(shù)據(jù)讀入累加器中;當(dāng)執(zhí)行輸出指令時(shí),則把累加器中的數(shù)據(jù)寫(xiě)入指定的端口中。
IN輸入指令
指令格式:
IN AL, 端口地址 或 IN AX, 端口地址端口地址存放在DX寄存器中
IN AL, DX 或 IN AX, DX- 指令功能:從8為端口讀入一個(gè)字節(jié)到AL寄存器,或從16為端口讀一個(gè)字到AX寄存器。16位端口由兩個(gè)地址連續(xù)的8為端口組成,從16位端口輸入時(shí),先將給定端口中的字節(jié)送進(jìn)AL,再把端口地址加1,然后將該端口中的字節(jié)讀入AH。
- IN指令有兩種格式:
- 第一種格式,端口地址(00~FFH)直接包含在IN指令里,共允許尋址256個(gè)端口。由于8086CPU可以直接訪問(wèn)地址為0000 ~ FFFFH的 64K 個(gè)I/O端口,當(dāng)端口地址號(hào)大于FFH時(shí),必須用第二種尋址方式。
- 第二種格式,即先將端口號(hào)送入DX寄存器,再執(zhí)行輸入操作。
OUT輸出指令
指令格式:
OUT AL, 端口地址 或 OUT AX, 端口地址端口地址存放在DX寄存器中
OUT AL, DX 或 OUT AX, DX- 指令功能:將AL中一個(gè)字節(jié)寫(xiě)到一個(gè)8位端口或把AX中的一個(gè)字寫(xiě)到一個(gè)16位端口。同樣對(duì)16位端口進(jìn)行輸出操作時(shí),也是對(duì)兩個(gè)連續(xù)的8位端口進(jìn)行輸出操作。
如下所示,讀取系統(tǒng)的月份并顯示。
assume cs:code, ds:data, ss:stackdata segmentdb 128 dup(0) data endsstack segment stackdb 128 dup(0) stack endscode segment start: mov ax, stackmov ss, axmov sp, 128call init_regcall show_monthmov ax, 4C00Hint 21H ;==================================================== init_reg: mov bx, 0B800Hmov es, bxret ;========================================================== show_month: mov al, 8 ; 月的內(nèi)存地址out 70H, al ; 1 2 1 + 30H '0'in al, 71H ; 0001 0010 ah 0000 0001Bmov ah, alshr ah, 1shr ah, 1shr ah, 1shr ah, 1and al , 00001111Badd ah, 30Hadd al, 30Hmov di, 160 * 10 + 40 * 2mov es:[di], ahmov es:[di + 2], alretcode ends end start
時(shí)間信息的
| 0 | 2 | 4 | 7 | 8 | 9 |
BCD 碼
| 0000 | 0001 | 0010 | 0011 | 0100 | 0101 | 0110 | 0111 | 1000 | 1001 |
以下是在DOSBOX中顯示系統(tǒng)當(dāng)前時(shí)間并實(shí)時(shí)刷新的程序代碼
; 以年/月/日 時(shí): 分: 秒的 形式顯示當(dāng)前的日期和時(shí)間 assume cs:code, ds:data, ss:stackdata segmentdb 128 dup(0) data endsstack segment stackdb 128 dup(0) stack endscode segment TIME_STYLE db 'YY/MM/DD HH:MM:SS', 0 ; y = year m = month d = day; h = hour m = minute s = second TIME_CMOS db 9, 8, 7, 4, 2, 0 start: mov ax, stackmov ss, axmov sp, 128call init_regcall show_clockmov ax, 4C00Hint 21H ;==================================================== show_clock: call show_time_styleshowTime: mov si, OFFSET TIME_CMOSmov di, 160 * 10 + 30 * 2mov cx, 6showDate: mov al, ds:[si]out 70H, alin al, 71Hmov ah, al ; 0011 0000shr ah, 1shr ah, 1shr ah, 1shr ah, 1and al, 00001111Badd ah, 30Hadd al, 30Hmov es:[di], ahmov es:[di + 2], alinc siadd di, 6loop showDatejmp showTime ; 鍵盤(pán)中斷ret;===================================================== init_reg: mov bx, 0B800Hmov es, bxmov bx, csmov ds, bxret ;========================================================== show_string: push dxpush dspush espush sipush dishowString: mov dl, ds:[si]cmp dl, 0je showStringRetmov es:[di], dladd di, 2inc sijmp showStringshowStringRet: pop dipop sipop espop dspop dxret ;========================================== show_time_style: mov si, OFFSET TIME_STYLEmov di, 160 * 10 + 30 * 2call show_stringretcode endsend start總結(jié)