組合語言 實驗14 201202版

2022-04-04 14:48:32 字數 2961 閱讀 5811

這篇是自己去年學習時候寫的,重新放出來,可以和現在的對比一下:

實驗要求:

程式設計:以「年/月/日  時:分:秒」的格式顯示出當前的日期、時間。

準備工作:因為cmos9號單元儲存的是年份資料,那麼該資料對應的是兩位的十進位制數字,拿今年2023年來說,9號單元裡儲存的就應該是bcd碼:00010001.為了驗證一下,同時也鞏固下cmos的讀寫操作,做了乙個小程式,如下:

-----------------------------------

assume cs:code

code segment

start:

mov al,9

out 70h,al

in al,71h

mov bl,al

mov al,8

out 70h,al

in al,71h

mov bh,al

mov ax,4c00h

int 21h

code ends

end start

-----------------------------------

debug跟蹤如下:

發現:(1)因為乙個記憶體單元表示為bcd碼的話只能表示兩位的十進位制數,而年份為4位,做這個程式的初衷就是檢驗年份資料是否為後兩位,可以看到最終bl=11h,即按bcd碼來理解的話就是為11(十進位制);沒有問題。

(2)單步跟蹤out 70h,...指令時,會繼續執行下一句後再響應單步中斷。至於是out指令,還是單獨僅針對out 70h,..指令才會出現這一情況,我暫時也不願意去深究了,至少明白了前幾章說的不僅僅是mov ss,。。。指令才會暫不響應單步中斷。

*分析:

在螢幕顯示字串,首先想到21h號中斷的9號子程式;那麼剩下的工作就是確定字串的內容和位址了:1、內容的確定,可通過讀取cmos時間資料獲得;2、位址的確定,可預設在資料段中。

以上是大致的框架,具體的流程如下:

(1)獲取時間資訊,存入指定資料段中;

(2)將上述時間資訊寫入預設字串中;完成最終輸出的字串;

(3)呼叫10h號中斷2號子程式,設定游標位置,即字串在螢幕上的輸出位置;

(4)呼叫21h號中斷9號子程式,輸出字串。

程式設計細節分析如下:

(1)資料段的設定:需要兩個指定區域分別存放已轉為數字字元的時間資料和預設的顯示字串;同時在獲取cmos時間資訊過程中,因為需要對其不同記憶體單元進行讀取,所以可採用實驗13(3)中的方法,將各時間單元位址單獨存於指定資料段,這樣就方便採用迴圈的方式將其寫入指定資料區;因此資料段的設定包括三部分內容:a、cmos各時間資訊的位址;b、存放已轉為數字字元的時間資料區;c、預設(及最終)的顯示字串。

(2)在完成最終顯示的字串的過程中,可以觀察到這個字串並不規整,總共17個字元,但只需要對其中部分進行修改,而且這部分需要修改的單元的偏移位址也不是規則的遞增;這樣就需要換個思路了,這裡需要修改的是時間資訊對應的位,在修改字串程式的過程中只需要判斷當前位是否為時間資訊位就可以了,那麼在預設的字串裡先將時間資訊位設定為0或者其他不為'/'or  '(space) or ':'就可以了。迴圈過程裡直接判斷當前位是否為0,為0則修改。

***:

assume cs:codesg,ds:data

data segment

d1 db 9,8,7,4,2,0

d2 db 12 dup (0)

d3 db '00/00/00 00:00:00','$'

data ends

codesg segment

start:

mov ax,data

mov ds,ax

mov bp,offset d1

mov si,offset d2

mov di,offset d3

;依次讀取時間資料寫入d2段

mov cx,6

s:mov al,ds:[bp]

out 70h,al

in al,71h

mov bl,al   ;暫存al

push cx     ;保護迴圈次數

mov cl,4

shr al,cl   ;得到十位

add al,30h

and bl,00001111b   ;得到個位

add bl,30h

mov ds:[si],al

inc si

mov ds:[si],bl

inc bp

inc si

pop cx

loop s

;將d2段資料寫入d3段,當d3段對應字元為'0'時候寫入

mov si,offset d2    ;重置

mov cx,17           ;d3段長度為迴圈次數

s1:mov al,ds:[di]

cmp al,30h

jnz next

mov al,ds:[si]

mov ds:[di],al

inc si

next:

inc di

loop s1

;呼叫10h中斷置游標位置

mov ah,2

mov bh,0

mov dh,10

mov dl,20

int 10h

;呼叫21h中斷顯示字串

mov dx,offset d3

mov ah,9

int 21h

mov ax,4c00h

int 21h

codesg ends

end start

*注意點:

在設定資料段data各資料區時候「標號」後面加了冒號(:),發現無法編譯通過,提示missing or unreachable cs.在群裡求助的時候大致知道了原因:就在於不該用冒號。這涉及到彙編裡標號和變數的區別,暫時我也無法弄清楚,畢竟才學到這裡。只需要知道:在資料段裡設定的標號(其實也許應該稱為變數)是不需要加":」的,而是用乙個空格位。而在**區里的標號則需要用冒號。

《組合語言》實驗 實驗

注意 db定義位元組型別變數,乙個位元組資料百佔1個位元組單度元,讀完乙個,偏移量加1 dw定義字型別變問量,乙個字資料佔2個位元組單元,讀完乙個,權偏移量加2 dd定義雙字型別變數版,乙個雙字資料佔4個位元組單元,讀完乙個,權偏移量加4 一開始用了乙個暫存器表示所有項,但是後來發現四個資料佔的位元...

組合語言實驗1 2

小寫字母變為大寫字母 data segment notic db please input the word 0ah,0dh data ends code segment assume cs code,ds data start mov ax,data mov ds,ax 填入ds mov cx,1...

組合語言實驗1 3

輸入10個字元,並反序輸出 data segment dd1 db 10 dup data ends code segment assume cs code,ds data start mov ax,data mov ds,ax lea bx,dd1 dd1的有效位址放入bx中 mov cx,0ah...