黄色在线观看视频-黄色在线免费看-黄色在线视频免费-黄色在线视频免费看-免费啪啪网-免费啪啪网站

查看全部128種考試
軟件水平考試
 考試動態 報考指南 歷年真題 模擬試題 復習資料 心得技巧 專業英語 技術文章 軟考論壇 考試用書
 程序員 軟件設計師 網絡管理員 網絡工程師 系統分析師 數據庫系統工程師
1
2
3
4
5
6
7
8
9
10
Exam8.com  
【字體: Casl匯編語言輔導(上)
Casl匯編語言輔導(上)
spks.exam8.com 來源:考試吧(Exam8.com) 更新:2004-12-27 13:32:00 軟件水平考試 考試論壇

一、Casl匯編語言語法介紹

學習一個匯編語言需要掌握3個要點:CPU 的可編程寄存器結構、尋址方式及指令系統、偽指令。

1、COMETCPU 的可編程寄存器

COMETCPU 字長 16 位,采用從左到右的編號。bit0 在最左邊(最高位),bit15 在最右邊(最低位)

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

1)16 位通用寄存器五個:

GR0、GR1、GR2、GR3、GR4

通用功能:各種算術邏輯運算

特殊功能:除 GR0 外都可作變址寄存器(地址指針)XR,GR0 可看成累加器。

GR4 兼作堆棧指針(SP)

2)指令計數器 PC 一個(16位)

存放正在執行的那條指令的第 1 個字的地址(一條指令占二個字),指令結束時,PC 中存放下一條指令的地址(一般為原指令地址 +2 )。

3)狀態寄存器 FR 一個(二位)

運算結果 FR0 FR1
大于  0 0
等于 0 1
小于 1 0

 

可以把 FR0 看成 SF(符號位),FR1 看成 ZF(零位位)

除了算術邏輯運算指令(包括移位指令)外,LEA 指令也會影響 FR

2、符號指令寫法與尋址方式

OP GR,ADR[,XR]

其中 OP 為操作碼;GR 為五個通用寄存器 GR0~GR4 之一;ADR 為一個 16 位的地址碼;XR 為四個變址寄存器 GR1~GR4 之一,[ ]表示可以省略。

1)直接尋址:當 [,XR] 省略時,為直接尋址。

2)變址尋址:有效地址 E = ADR +(XR),當 ADR = 0 時,為寄存器間接尋址。

3)立即數尋址:Casl 沒有立即數尋址。但在 LEA 指令中,當 [,XR] 省略時,可作立即數傳送。沒有立即數運算指令。

4)寄存器尋址:Casl 也沒有寄存器尋址(對源操作數)。但 LEA 指令當 ADR = 0 時,可作寄存器尋址(只用于數據傳送)。

3、Casl指令系統

1)取數指令 LD:內存→寄存器

LD GR,ADR[,XR]

2)存數指令 ST:寄存器→內存

ST GR,ADR[,XR]

3)加法 ADD、減法 SUB、邏輯與 AND、邏輯或OR、邏輯異或 EOR指令:

ADD
SUB
AND GR,ADR[,XR]
OR
EOR

內存 OP 寄存器→寄存器

4)算術比較 CPA:

兩個帶符號數比較,結果不回送,只影響標志位。

CPA GR,ADR[,XR]

5)邏輯比較 CPL:兩個無符號數比較,結果不回送,只影響標志位。

CPL GR,ADR[,XR]

6)算術左移 SLA、算術右移 SRA:把操作數看成帶符號數。對寄存器操作數進行移位(GR 的第 0 位——符號位不變。右移時空出的其余位補與第 0 位相同的 1 或 0 ;左移時空出的位補 0 ),位數由有效地址 E 決定。

SLA GR,ADR[,XR]
SRA

7)邏輯左移 SLL、邏輯右移 SRL:把操作數看成無符號數。對寄存器操作數進行移位(不管左右移,GR 空出的位補 0 ),位數由有效地址 E 決定。

SLL GR,ADR[,XR]
SRL

8)取有效地址指令LEA:E→寄存器

LEA GR,ADR[,XR]

該指令有幾個特殊用途:

【例1】LEA GR0,41H 把立即數 41H 送給 GR0

【例2】LEA GR0,0,GR1 把寄存器 GR1 的內容送給 GR0

【例3】LEA GR1,1,GR1 寄存器 GR1 的內容加 1(相當于 8086 匯編中的 INC 指令)

【例4】LEA GR1,-1,GR1 寄存器 GR1 的內容減 1(相當 8086 匯編中的 DEC 指令)

【例5】LEA GR1,N,GR1 寄存器 GR1 的內容加 N(相當于立即數加法)

【例6】LEA GR1,-N,GR1 寄存器 GR1 的內容減 N(相當于立即數減法)

9)無條件轉移指令JMP與條件轉移指令JPZ(不小于轉)、JMI(小于轉)、JNZ(不等于轉)、JZE(等于轉)

JMP
JPZ
JMI ADR[,XR]
JNZ
JZE

●當地址碼中缺 [XR] 時,所有轉移指令為直接轉移( ADR 即為轉移地址)

     當地址碼中有 [XR] 時,所有轉移指令為間接相對接轉移

●JPZ 與 JMI 根據符號位 FR0 作為判斷條件

     JNZ 與 JZE 根據零位位 FR1 作為判斷條件

10)進棧 PUSH 與出棧 POP:

(1)進棧指令 PUSH:

PUSH ADR[,XR]

(SP)-1→SP,E→(SP)

(2)出棧指令 POP:

POP GR

((SP))→GR,(SP)+1→SP

注意:出棧指令的目的寄存器是 GR0~GR4,而進棧指令的源操作數不包括 GR0。 

11)子程序調用CALL與返回 RET指令

(1)子程序調用指令 CALL:

CALL ADR[,XR]

 (SP)-1→SP,(PC)+2→(SP),E→(PC)

(2)子程序返回指令 RET:

RET

((SP))→PC,(SP)+1→SP

4、偽指令

1)START:程序開始

2)END:程序結尾

3)常量定義指令 DC

此偽指令與其它匯編語言中的 DB 指令似。利用 DC 指令可定義:

(1)定義十進制常數:

十進制常數名 DC n

其中 -32768 < n ≤65535

(2)定義字符串常數:

字符串常數名 DC '字符串'

(3)定義十六進制常數:

十六進制常數名 DC #h

其中 0000 ≤ h ≤FFFF

(4)定義地址:

地址常數 DC LABLE

其中 LABLE 是程序中的地址標號

因為 Casl 沒有立即數運算指令,所以需要與立即數進行算術邏輯運算時,都要將立即數定義為內存常數進行運算。

4)變量定義指令 DS用來保留指定字數的存儲區域

[LABLE] DS n

其中 n 是十進制常數(≥0),當 n=0 時,存儲區域不存在,但標號 LABLE 仍然有效,即代表下一字的地址。

5)宏指令:IN、OUT、EXIT

Casl 中有進行輸入、輸出及結束程序等宏指令,而沒有定義輸入、輸出符號指令,這類處理由操作系統完成。

程序中出現宏指令時,Casl 生成調用操作系統的指令串,但是,生成的指令串字數不定。

執行宏指令時,GR 的內容保持不變,而 FR 的內容不確定。

(1)輸入宏指令 IN:

[LABLE] IN ALABLE,NLABLE

宏指令 IN 從輸入裝置上輸入一個記錄,紀錄中的信息(字符)依次按字符數據的形式存放在標號為 ALABLE 開始的區域內,已輸入的字符個數以二進制數形式存放在標號為 NLABLE 的字中,紀錄之間的分隔符號不輸入。

(2)輸出宏指令 OUT:

[ LABLE] OUT ALABLE,NLABLE

宏指令 OUT 將存放在標號為 ALABLE 開始的區域中的字符數據作為一個記錄向輸出裝置輸出,輸出的字符個數由標號為 NLABLE 的字的內容指定。輸出時,若要紀錄間的分隔符號,由操作系統自動插入輸出。

(3)宏指令 EXIT :

[LABLE] EXIT

宏指令 EXIT 表示程序執行的終止,控制返回操作系統。

二、基本程序結構

1、順序程序(略)

2、分枝程序

1)簡單分支程序

將比較指令(或其它能使標志位發生變化的指令)和條件轉移指令結合,可實現分支程序。簡單分支程序有兩種形式:

在匯編語言中,采用圖a的結構容易出錯,例如把GB0中的十六進制數轉換成 ASCII 碼可分成兩段, 0~9 的 ASCII 碼是 30H~39H ,即加 30H ;A~F 的ASCII 碼是 41H~45H ,即加 37 H。兩種結構的程序如下:

圖a結構

圖b結構

CPL GR0,C10 CPL GR0,C10
JMI L1 JMI L1
ADD GR0,C37 ADD GR0,C7
JMP L2 L1 ADD GR0,C30
L1 ADD GR0,C30  …
L2 C10 DC 10
C10 DC 10 C7 DC 7
C37 DC #37 C30 DC #30
C30 DC #30

若采用圖a的結構,很容易把JMP L2漏掉,變成A~F 的ASCII 碼加了67H。

2)多岔分支程序

可以用多條比較指令和條件轉移指令實現多岔分支。

但用散轉表實現多岔分支則程序更為簡練,其思路是在散轉表中存放各個分支程序的入口地址,用查表方法將入口地址放入變址寄存器,然后用JMP指令或CALL指令的間接尋址方式使程序轉到此入口。

【例1】根據鍵盤輸入命令轉入各命令處理程序

SB START
AGAIN IN

ALABLE,NLABLE

;輸入一個字符串
LD GR1,NLABLE ;字符串長度
LEA GR1,0,GR1
JZE AGAIN ;若字符串長度 =0,重輸
LD GR1,ALABLE ;將第一個字符放到GR1中
LEA GR1,-65,GR1 ;減去"A"的ASCII碼
JMI AGAIN ;若該字符<"A",重輸
CPA GR1,C4
JPZ AGAIN ;若該字符>"D",重輸
LD GR2,ENTRY,GR1 ;將散轉表中的一項地址放入GR2
CALL  0,GR2 ;轉入地址所指子程序
JMP AGAIN
ALABLE DS 5 ;輸入字符串緩沖區
NLABLE DS 1 ;輸入字符串長度
C4 DC 4 ;常數 5
ENTRY DC ASUBR ;子程序A 入口地址
DC BSUBR ;子程序B 入口地址
DC CSUBR ;子程序C 入口地址
DC DSUBR ;子程序D 入口地址
END

在散轉表中也可存放轉移到各個分支程序入口的轉移指令,然后用變址尋址方式的JMP指令或CALL指令使程序轉到此入口。
【例2】

SB START
AGAIN IN

ALABLE,NLABLE

;輸入一個字符串
LD GR1,NLABLE ;字符串長度
LEA GR1,0,GR1
JZE AGAIN ;若字符串長度 =0,重輸
LD GR1,ALABLE ;將第一個字符放到GR1中
LEA GR1,-65,GR1 ;減去"A"的ASCII碼
JMI AGAIN ;若該字符<"A",重輸
CPA GR1,C4
JPZ AGAIN ;若該字符>"D",重輸
SLL GR1,1 ;散轉表每項占2 字
JMP ENTRY,GR1
ALABLE DS 5
NLABLE DS 1
C4 DC 4
ENTRY JMP ASUBR
JMP BSUBR
JMP CSUBR
JMP DSUBR
END

3、循環程序

循環程序也是用轉移指令實現,循環的退出一般用循環計數器實現,也可用其它條件來控制退出。

1)用循環計數器控制

【例1】將SD處的100個數搬到TD處(搬家程序)

SB START
LEA GR1,100 ;循環計數器
LEA GR2,0 ;偏移地址指針
LOOP LD GR0,SD,GR2 ;源操作數→GR0
ST GR0,TD,GR2 ;GR0→目的操作數
LEA GR2,1,GR2 ;修正偏移地址指針
LEA GR1,-1,GR1 ;搬完否?
JNZ LOOP
EXIT
SD DS 100
TD DS 100
END

當源操作數和目的操作數有重迭時,若源操作數在目的操作數的前面,則必須采用從下往上的搬法,即先搬最后一個,再一個一個往前搬。
【例2】將 SD 處的 100 個數搬到 TD 處(有重迭)

SB START
LEA GR1,100 ;循環計數器
LEA GR2,99 ;偏移地址指針
LOOP LD GR0,SD,GR2 ;源操作數→GR0
ST GR0,TD,GR2 ;GR0→目的操作數
LEA GR2,-1,GR2 ;修正偏移地址指針
LEA GR1,-1,GR1 ;搬完否?
JNZ LOOP
EXIT
SD DS 1
TD DS 100
END

2)循環次數可能為 0 的循環程序
前面的例子無法實現循環次數可能為0的循環程序(如用連加實現兩個數相乘的算法),因為循環計數器預置為0時,實際的循環次數是65536。

【例2】將 A 和 B 兩個整數相乘和放到 C 中(不考慮溢出)

SB START
LD GR1,B ;乘數作循環計數器
LEA GR0,0 ;乘積清0
LOOP LEA GR1,0,GR1
JZE L1 ;若乘數為0,退出循環
ADD GR0,A ;被乘數加到乘積中
LEA GR1,-1,GR1 ;加完否?
JMP LOOP
L1 ST GR0,C  ;乘積→C
EXIT
A DS 1
B DS 1
C DS 1
END

3)循環次數不定的循環程序
不用循環計數器,而用其它方法控制循環的退出。
【例4】測試字符串STR的長度,并將它保存到L中

SB START
LEA GR1,0 ;字符串長度計數器(兼地址指針)清0
LOOP LD GR0,STR,GR1 ;取一字符
CPL GR0,FEND
JZE L1 ;若是結束符,退出循環
LEA GR1,-1,GR1 ;長度計數器+1
JMP LOOP
L1 ST GR0,L ;長度→L
EXIT
L DS 1
FEND DC '$'
STR DC 'This is a sample$'
END

 4)多重循環

【例5】冒泡排序程序。

一組有符號數al(i=1,2,…,100),存放在Al開始的連續單元中。下面一程序將這組數在原來的內存區中由大到小重新排序。

SB START
LEA GR1,99
ST GR1,CN ;外循環計數器初值
L1 LEA GR1,0 ;外循環指針
LEA CR2,1 ;內循環指針兼計數器初值
LEA GR3,0 ;交換標志置0
L2 LD GR0,A1,GR1
CPA GR0,A1,GR2
JPZ  L3 ;內循環體,若Ai≥Ai+1,不動
LD GR4,A1,GR2 ;若Ai<Ai+1,交換
ST GR4,A1,GR1
ST GR0,A1,GR2
LEA GR3,1 ;交換標志置1
L3 LEA GR1,1,GR1 ;內循環調整
LEA GR2,1,GR2
CPL GR2,CN
JZE L2 ;內循環控制
JMI L2
LEA CR3,0,CR3
JZE L4 ;本次內循環交換標志為0,排序結束
LD GR4,CN ;外循環計數減1
LEA GR4,-1,GR4
JZE L4 ;排序結束
ST  GR4,CN
JMP L1
L4 EXIT
A1 DS 100
CN DS 1
END

  這是一個二重循環結構的程序。程序中采用冒泡排序的方法,首先從第1個單元開始,依次把相鄰兩個元素比較,即第1個單元內的數與第2個單元內的數比較,第2個單元內的數與第3個單元內的數比較,…第99個單元與第100個單元的數相比較。每次把較大者放在前面單元,較小者放在后面單元。這樣第一次遍歷做了n-1次比較,最后最小的元素放在第100個單元。

第二次遍歷再從頭開始,依次將相鄰兩個元素進行比較,把n-1個元素遍歷一次需做n-2次比較,這樣,第99個單元存放全部元素中次小元素。

如此反復,小的元素往下,大的元素向上猶如汽泡上浮,因此這種排序的方法給它一個形象的名字,叫做冒泡算法。在程序中還設GR3為交換標志,若本次內循環結束交換標志為0,說明沒有交換。即所有的Ai≥Ai+1,排序結束。
4、子程序

所謂子程序是指完成一定功能的指令序列,在主程序的若干地方可以用CALL指令對它調用,子程序結束時通過RET指令返回主程序。在子程序中,如果沒有特別說明,則子程序中所要使用到的寄存器要保護。在子程序的開始用PUSH指令將子程序中要使用的寄存器保護,在返回前用POP指令恢復。主程序與子程序可以處在同一個程序中,此時,主程序對子程序的調用稱為程序內的調用,CASL中也允許主程序與子程序不在同一個程序中,這樣的調用就稱為程序間凋用。

在子程序中一般不將GR4作為通用寄存器使用,因為GR4作為棧頂指針。如果其它通用寄存器不夠用,要使用GR4,則先將GR4中的棧頂指針值保存,然后使用GR4,GR4使用完后,立即恢復棧指針的值。

1)參數傳遞

主程序調用子程序時,通常要向子程序傳遞參數(入口參數)。子程序結束,也會有數據送回主程序(返回參數)。當參數較少時,主程序將參數存于寄存器(GR0~GR3)傳遞給子程序;也可放于內存給子程序;當傳遞參數較多時,通常存于內存(參數表),并將參數表的首地址存于寄存器傳遞給子程序;也可以通過堆棧傳遞參數值。

【例1】寄存器傳遞參數

MAIN START
LD GR0,A ;被加數送GR0
LEA GR1,B ;加數送GR1
CALL SUBA
ST GR0,C ;結果回送
……
EXIT
SUBA ADD GR0,0,GR1
RET
A DC 56
B DC 89
C DS 1
D DC 186
E DC 567
F DS 1
END

【例2】內存傳遞參數

MAIN START
LD GR0,A ;被加數送GR0
LD GR1,B
ST GR1,BUF ;加數送BUF內存單元
CALL SUBA
ST GR0,C ;結果回送
……
EXIT
SUBA ADD GR0,BUF
RET
BUF DS 1
A DC 56
B DC 89
C DS 1
D DC 186
E DC 567
F DS 1
END

【例3】參數表傳遞參

MAIN START
LEA  GR1,LIST ;參數表首址送GR1
CALL SUBA
EXIT
SUBA LD GR0,0,GR1 ;被加數
ADD GR0,1,GR1 ;與加數相加
ST GR0,2,GR1 ;結果回送
RET
LIST DC 56
DC 89
DS 1
END

【例4】堆棧傳遞參數

MAIN START
LD GR1,A
PUSH 0,GR1 ;被加數壓入堆棧
LD GR1,B
PUSH 0,GR1 ;加數壓入堆棧
LEA GR1,C
PUSH 0,GR1 ;結果地址壓入堆棧
CALL SUBA
LEA GR4,3,GR4 ;堆棧指針退回
EXIT
SUBA LD GR0,3,GR4 ;被加數
ADD GR0,2,GR4 ;與加數相加
LD GR1,1,GR4 ;結果地址
ST GR0,0,GR1 ;結果回送
RET
A DC 56
B DC 89
C DS 1
END

2)子程序的返回

子程序通過RET指令返回主程序。RET指令的功能是將棧頂的返回地址置入PC。一般情況,應該保證返回時的堆棧指針SP(GR4)與調用時一致。以保證正確返回。但CASL中,GR4兼作通用寄存器,變址器和棧頂指針,因此在子程序中可以通過GR4修改返回地址,這樣子程序返回時,就不一定返回到主程序的調用點下面的一條指令。在早期的程序員CASL試題中常常利用這一技巧。

3)現場保護

通常情況下,子程序都應該保護它所使用過的寄存器。因PUSH指令不能保護GR0,所以GR0用ST指令保護,用LD指令恢復。

【例4】無符號乘法。

有兩個無符號數N1,N2,下面一子程序實現N1×N2返回。調用子程序時GR1存放參數N1、N2和相乘結果的存放區域的首地址,如下圖所示。設相乘過程不會產生溢出。

GR1+0 N1
+1 N2
+2 結果
MULT START
ST GR0,SAVE
PUSH 0,GR2 ;保護寄存器
PUSH 0,GR3
LEA GR2,0 ;部分積清零
LEA GR3,16 ;循環計算器
LD GR0,1,GR1 ;取出乘數N2
LOOP SLL GR2,1 ;部分積左移一位
SLL GR0,0 ;測乘數N2最高位是否為1
JPZ L1 ;若為0,跳過這一位
ADD GR2,0,GR1 ;若為1,部分積加上被乘數
L1 SLL GR0,1 ;乘數左移一位,算下一位
LEA GR3,-1,GR3 ;16位算完否?
JNZ LOOP
ST GR2,2,GR1 ;存放乘積
LD GR0,SAVE ;恢復寄存器的值
POP GR3
POP GR2
RET
SAVE DS 1
END

象手算乘法一樣,由于兩個數是二進制數,所以唯一的問題是乘0還是乘1;顯然,乘0結果為0,而乘1則結果與開始的數(被乘數)相同。因此在二進制乘法中每一步都可以簡化成下列運算:
如果乘數中現有位為1,則將被乘數加到部分積上,為0則不加。剩下的問題是部分積和被乘數每次相加要進行移位,保證每次相加都正確對準。乘法過程可分成以下幾步:

(1)積清0,設置計數器初值16。

(2)積左移1位。

(3)乘數最高位是否為1。

(4)若為1,則被乘數加積。

(5)乘數左移1位,計數器減1,若不為0轉(2)。

程序中GR0存乘數,GR2存積,GR3為計數器

二、匯編語言常用子程序

1、拆字與拼字:

【例1】將 GR0 中的四位 BCD 碼從高到低依次存放到 GR2 所指的四個內存單元中。

START
LEA GR3,4 ;循環計數器
L1 ST GR0,REG ;保護其余幾位 BCD 碼
AND GR0,C000F ;屏蔽高 3 位,留下最低 1 位 BCD 碼
ST GR0,3,GR2 ;將此位 BCD 碼存放到 GR2 所指第四個內存單元
LD GR0,REG ;恢復其余幾位 BCD 碼
SRL GR0,4 ;將已處理過的此位 BCD 碼移出
LEA GR2.-1,GR2 ;地址指針減 1
LEA GR3,-1,GR3 ;循環計數器減 1
JNZ L1 ;未處理完,繼續
RET
C000F DC #000F ;十六進制常數,屏蔽高 3 位 BCD 碼用
REG DS 1 ;暫存單元
END

【例2】將存放在 GR2 所指的四個內存單元中的四位 BCD 碼依從高到低順序壓縮到 GR0 中 。

START
LEA GR0,0 ;GR0 清 0
LEA GR3,4 ;循環計數器
L1 SLL GR0,4 ;將已處理過的 BCD 碼移到高位
LD GR1,0,GR2 ;GR1 用作臨時工作寄存器
AND GR1,C000F ;屏蔽高 12 位
ST GR1,0,GR2 ;對內存單元中的 BCD 碼預處理
ADD GR0,0,GR2 ;將已處理過的此位 BCD 碼加到 GR0 低位
LEA GR2.1,GR2 ;地址指針指向下一位 BCD 碼
LEA GR3,-1,GR3 ;循環計數器減 1
JNZ L1 ;未處理完,繼續
RET
C000F DC #000F ;十六進制常數,屏蔽高 12 位二進制數
END

2、數字與 ASCII 碼之間的相互轉換:

十進制數字 0~9 的 ASCII 碼是 30H~39H ,所以只要將十進制數(BCD 碼)加 30H 就是對應的 ASCII 碼。

十六進制數轉換成 ASCII 碼可分成兩段, 0~9 的 ASCII 碼是 30H~39H ,即加 30H ;A~F 的ASCII 碼是 41H~45H ,即加 37 H。

【例1】將 GR0 中的四位 BCD 碼化成 ASCII 碼從高到低依次存放到字符串變量 STR 中。

START
LEA GR2,3 ;相對于 STR 首址的地址指針
LEA GR3,4 ;循環計數器
L1 ST GR0,REG ;保護其余幾位 BCD 碼
AND GR0,C000F ;屏蔽高 3 位,留下最低 1 位 BCD 碼
ADD GR0,C30 ;轉換成 ASCII 碼
ST GR0,STR,GR2 ;將 ASCII 碼存放到 GR2 所指第四個內存單元
LD GR0,REG ;恢復其余幾位 BCD 碼
SRL GR0,4 ;將已處理過的此位 BCD 碼移出
LEA GR2.-1,GR2 ;地址指針減 1
LEA GR3,-1,GR3 ;循環計數器減 1
JNZ L1 ;未處理完,繼續
RET
C000F DC #000F ;十六進制常數,屏蔽高 3 位 BCD 碼用
C30 DC #30 ;十六進制常數 30
STR DS 4
REG DS 1 ;暫存單元
END

【例2】將 GR0 中的 16 位二進制數化成四位十六進制數 ASCII 碼從高到低依次存放到字符串變量 STR 中。

START
LEA GR2,3 ;相對于 STR 首址的地址指針
LEA GR3,4 ;循環計數器
L1 ST GR0,REG ;保護其余幾位二進制數
AND GR0,C000F ;屏蔽高 12 位,留下最低 4 位二進制數
CPL GR0,C10 ;< 10 否?
JMI L2 ;< 10 跳過加 7 ,只加 30H
ADD GR0,C7 ;≥ 10,加 30H 前先加上 7
L2 ADD GR0,C30 ;加上 30H
ST GR0,STR,GR2 ;將 ASCII 碼存放到 GR2 所指第四個內存單元
LD GR0,REG ;恢復其余幾位二進制數
SRL GR0,4 ;將已處理過的此 4 位二進制數移出
LEA GR2.-1,GR2 ;地址指針減 1
LEA GR3,-1,GR3 ;循環計數器減 1
JNZ L1 ;未處理完,繼續
RET
C000F DC #000F ;十六進制常數,屏蔽屏蔽高 12 位二進制數
C30 DC #30 ;十六進制常數 30
C10 DC 10 ;十進制常數 10
C7 DC 7 ;常數 7
STR DS 4
REG DS 1 ;暫存單元
END

【例3】將字符串 STR 中的四位十六進制數的 ASCII 碼化成 16 位二進制數放到 GR0 中 。

START
LEA GR0,0 ;GR0 清 0
LEA GR2,0 ;相對于 STR 首址的地址指針
LEA GR3,4 ;循環計數器
L1 SLL GR0,4 ;將已處理過的十六進制數移到高位
LD GR1,STR,GR2 ;GR1 用作臨時工作寄存器
AND GR1,C00FF ;屏蔽高 8 位
SUB GR1,C30 ;減去30H
CPL GR1,C0A ;< 10 否?
JMI L2 ;< 10 ,完成轉換
SUB GR1,C7 ;≥ 10,再減去 7
L2 ST GR1,STR,GR2 ;將 STR 中的 ASCII 碼轉換成十六進制數
ADD GR0,STR,GR2 ;將此位十六進制數加到 GR0 低位
LEA GR2.1,GR2 ;地址指針指向下一位 ASCII 碼
LEA GR3,-1,GR3 ;循環計數器減 1
JNZ L1 ;未處理完,繼續
RET
C00FF DC #00FF ;十六進制常數,屏蔽高 8 位用
C30 DC #30 ;十六進制常數 30
C0A DC #0A ;十六進制常數 0A
C7 DC 7 ;常數 7
STR DS 4
END

3、利用加減法及移位指令做乘法:

1)左移指令可將操作數乘 2 的整數次方(2、4、8、16);右移指令可將操作數除以 2 的整數次方。

若操作數是無符號數,用邏輯移位指令;若操作數是有符號數,用算術移位指令。

【例1】將 GR0 中的二進制數乘以 8。

SLL GR0,3

【例2】將 GR0 中的帶符號二進制數除以 4。

SRA GR0,2

2)將移位指令和加減法結合起來可完成乘數不是 2 的整數次方的乘法運算。

【例1】將 GR0 中的二進制數乘以 10。

START
SLL GR0,1
ST GR0,REG
SLL GR0,2
ADD GR0,REG
RET
REG DS 1
END

【例2】將 GR0 中的二進制數乘以 7。

START
ST GR0,REG
SLL GR0,3
SUB GR0,REG
RET
REG DS 1
END

4、二進制數與十進制數的轉換

1)二化十:

將二進制數轉換為十進制數的一種常用算法是將被轉換的二進制數依次被 10i( 對 16 位二進制數,i為 4、3、2、1、0)除,所得的商即為該十進制數位的值,其余數再被下一個 10i 除。一般用減法代替除法,即一邊減 10i,一邊計數器加 1,直到不夠減再進行下一位 10i-1。以求得十進制數的各位數。

例如:一個相當于十進制數 34635 的二進制數,可先用 10000 去減,可減 3 次,得萬位數是 3;再用 1000 去減,得千位數是 4;……

【例1】將 GR0 中的二進制數轉換為十進制數的ASCII 碼放入字符串 STR 中。

START
LEA GR1,0 ;減數表及字符串指針
LEA GR2,5 ;循環計數器
L1 LEA GR3,48 ;該十進制位的數碼預置 0 的 ASCII 碼
L2 LEA GR3,1,GR3 ;數碼位的 ASCII 碼加 1
SUB GR0,SNO,GR1 ;操作數減去 10
JPZ L2 ;夠減,繼續
ADD GR0,SNO,GR1 ;不夠減,操作數及數碼位的 ASCII 碼恢復
LEA GR3,-1,GR3
ST GR3,STR,GR1 ;轉換好的該位 ASCII 碼存入結果字符串
LEA GR1,1,GR1 ;地址指針加 1
LEA GR2,-1,GR2 ;循環計數器減 1
JNZ L1 ;未結束,繼續下一位
RET
SNO DC 10000
DC 1000
DC 100
DC 10
DC 1
STR DS 5 ;轉換結果字符串
END

1)十化二:

將十進制數轉換為二進制數的算法基礎是下面公式:

N = (Dn-1*10n-1+Dn-2*10n-2+……+D1*101+D0*100

  = ((…((Dn-1*10+Dn-2)*10+……+D1)*10+D0)*10

可以用循環程序實現此公式,*10 可用移位及加法指令完成。

【例2】將存放在字符串 STR 中的五位十進制數(<65536)的 ASCII 碼轉換成二進制數放到 GR0 中 。

START
LEA GR0,0 ;轉換結果寄存器清 0
LEA GR2,5 ;循環計數器
LEA GR1,0 ;地址指針(偏移量)
L1 SLL GR0,1 ;轉換結果*10,先乘以 2
ST GR0,REG ;暫存 2*X
SLL GR0,2 ;2*X*4=8*X
ADD GR0,REG ;8*X + 2*X
LD GR3,STR,GR1 ;取一位 ASCII 碼
AND GR3,C000F ;將 ASCII 碼變成 BCD 碼
ST GR3,REG ;結果暫存
ADD GR0,REG ;將新的一位 BCD 碼加到轉換結果中
LEA GR1,1,GR1 ;地址指針加 1
LEA GR2,-1,GR2 ;循環計數器減 1
JNZ L1 ;未結束,繼續下一位
RET
C000F DC #000F ;十六進制常數,屏蔽高 12 位二進制數
STR DC '35475'
REG DS 1 ;暫存單元
END

5、求累加和

【例1】將變量 NUMBER 中的 5 個二進制數累加后放入變量 SUM 中。

START
LEA GR2,NUMBER ;地址指針
LEA GR3,5 ;循環計數器
LEA GR0,0 ;累加和清0
L1 ADD GR0,0,GR2 ;累加
LEA GR2,1,GR2 ;地址指針指向下一個二進制數
LEA GR3,-1,GR3 ;計數器減1
JNZ L1 ;未完,繼續
ST GR0,SUM ;累加結束,累加和送入 SUM 單元
RET
NUMBER DS 5
SUM DS 1
END

【例2】將自然數1~16累加后放入變量 SUM 中。

START
LEA GR1,0 ;地址指針
LEA GR0,0 ;累加和清 0
L1 LEA  GR1,1,GR1 ;自然數加1
ST GR1,SUM ;加數(自然數)送入內存暫存
ADD GR0,SUM ;累加
CPA GR1,A
JNZ L1 ;未完,繼續
ST GR0,SUM ;累加結束,累加和送入 SUM 單元
EXIT
A DC 16
SUM DS 1
END

LEA GR1,0
LEA GR0,0 ;累加和(被加數)
CF LEA GR1,1,GR1
 ;
ADD GR0,C
 
JNZ CF
ST GR0,B
EXIT
A DC 16

6、利用遞歸方法求5的階乘

START ;主程序
LEA GR1,5 ;入口參數5(階乘)→GR1
CALL FACT ;調用FACT子程序
EXIT
FACT LEA GR1,0,GR1
JNZ IIA ;GR1未到0,繼續遞歸
LEA GR1,1 ;GR1=0,退出遞歸
RET
IIA PUSH 0,GR1 ;保護這一級乘數
LEA GR1,-1,GR1 ;乘數減1
CALL FACT ;繼續調用FACT子程序自己
POP GR1 ;逐級退出遞歸,恢復本級乘數
LEA GR0,0
CALL MUL ;乘上本級乘數
RET
MUL ADD GR0,RESUL
LEA GR1,-1,GR1
JNZ MUL
ST GR0,RESUL
RET
RESUL DC 1
END

 


轉帖于:軟件水平考試_考試吧
文章搜索  
看了本文的網友還看了:
·軟件工程習題200題之二  (2004-12-29 23:54:00)
·軟件工程習題200題之一  (2004-12-29 23:53:00)
·Casl匯編語言輔導(下)  (2004-12-29 23:52:00)
軟件水平考試權威輔導教材: 訂書電話:010-62168566  更多>>>
網友評論
昵 稱: *  評 分: 1分 2分 3分 4分 5分
標題:   匿名發表    (共有條評論)查看全部評論>>
版權聲明 -------------------------------------------------------------------------------------
  如果軟件水平考試網所轉載內容不慎侵犯了您的權益,請與我們聯系,我們將會及時處理。如轉載本軟件水平考試網內容,請注明出處。
關于本站  網站聲明  廣告服務  聯系方式  付款方式  站內導航  客服中心  友情鏈接  考試論壇  網站地圖
Copyright © 2004-2008 考試吧軟件水平考試網 All Rights Reserved    
中國科學院研究生院權威支持(北京) 電 話:010-62168566 傳 真:010-62192699
百度大聯盟黃金認證  十佳網絡教育機構  經營許可證號:京ICP060677
主站蜘蛛池模板: 两个人看的www中文字幕 | 国产免费黄色网址 | 8000av在线| 日韩在线天堂免费观看 | 久草看片 | 国产精品久久久久一区二区 | 九九免费精品视频在这里 | 一级毛片在线观看免费 | 777丰满影院| 天天国产视频 | 欧美2区| 激情五月社区 | 亚洲三区视频 | 日本精品一区二区三区在线观看 | 欧美日韩综合在线视频免费看 | 久久国产高清 | 伦理剧在线中文 | 婷婷国产天堂久久综合五月 | 国产欧美日本 | 日韩美女一级毛片a | 国产 欧美日韩 在线播放 | 国产色婷婷精品综合在线手机播放 | 黄色一级毛片看一级毛片 | 日本大学生xxxx视频 | 午夜网站在线观看 | 国产区1 | 久久亚洲免费视频 | 毛片高清 | 国产xxxx做受性欧美88 | 成人 在线欧美亚洲 | 成人福利网址 | 亚洲综合网国产福利精品一区 | 亚洲国产男人本色在线观看的a站 | 性欧美video另类hd亚洲人 | 成人精品视频一区二区三区尤物 | 夭天曰天天躁天天摸在线观看 | 亚洲视频国产视频 | 黑人videos巨大hd粗暴 | 亚洲视屏一区 | 日本视频中文字幕 | 国产亚洲欧美日韩在线一区 |