跳至內容

A-level 計算機 2009/AQA/處理和程式設計技術/機器操作和組合語言

來自華夏公益教科書,開放的書籍,開放的世界

機器碼

[編輯 | 編輯原始碼]

機器碼是一種二進位制程式語言,是 CPU 最容易處理的形式。每行程式碼包含一個 **運算子**(指令的二進位制表示)和一個 **運算元**(給定指令要操作的資料)。

組合語言指令

[編輯 | 編輯原始碼]

組合語言是機器碼和 **高階語言** 之間的中間階段,通常可以透過直接翻譯轉換為機器碼。與機器碼一樣,組合語言指令包含運算子和一個或多個運算元。

每個處理器可用的確切指令範圍將因處理器而異。但是,任何給定處理器都有四種不同型別的指令可用。

資料傳輸指令

[編輯 | 編輯原始碼]

資料傳輸指令用於在 **暫存器** 之間以及暫存器和 **主記憶體** 之間移動資料。

算術指令

[編輯 | 編輯原始碼]

算術指令可用於對暫存器內容執行算術函式。一些處理器允許使用多種算術指令,例如加法、減法、乘法、除法和增量。其他一些只允許加法和減法。

邏輯指令

[編輯 | 編輯原始碼]

邏輯指令可用於對暫存器內容執行邏輯函式。邏輯指令的一些示例包括:and、or、xor 和 not。這些在掩碼數字時很有用,例如將 ASCII 轉換為數字的二進位制表示或將 ASCII 從大寫轉換為小寫。

只有當比較兩個 1 時,答案才為 1。

只有當比較中存在一個或多個 1 時,答案才為 1。

或 EOR(異或/異或)
只有當比較中恰好有一個 1 時,答案才為 1。

將所有 1 變成 0,所有 0 變成 1。這對於二進位制補碼很有用。

遮蔽

[edit | edit source]

例如,將十進位制數 3 的 ASCII 表示形式轉換為二進位制表示形式:十進位制數 3 的 ASCII 表示形式為 。二進位制表示形式為 。所以,為了從 ASCII 轉換為二進位制,我們需要遮蔽掉二進位制表示形式的前四位,並保留後四位。有多種方法可以做到這一點。

AND solution

Note that we have set the last four bits to 1, try converting another ASCII number and see if this mask works for all of them?

XOR solution

Note that we only set the two bits different between the ASCII and binary to 1.  Try this mask for other ASCII numbers
Rules of Thumb
AND, if you want to keep a part of a number, AND 1 with it.  If you want to blank out part of a number, AND 0 with it.
OR, if you want to keep a part of a number, OR 0 with it.  If you want to set part of a number, OR 1 with it.
XOR, if you want to keep a part of a number, XOR 0 with it.  If you change a one to a zero XOR a 1 with it.

處理無關緊要

[edit | edit source]

考試可能會問你一些需要你為特定數字構建掩碼的問題,檢查 1 和 0,以及忽略某些單元格的內容。下面是一個快速參考表(X = 無關緊要的輸入)

AND

如果你將除了所需輸入以外的任何其他輸入放入方程中,結果將不正確。你現在可以將它與數字 進行比較,如果相等,那麼你就知道收到了正確的輸入。

OR

如果你將除了所需輸入以外的任何其他輸入放入方程中,結果將不正確。你現在可以將它與數字 進行比較,如果相等,那麼你就知道收到了正確的輸入。

彙編中的示例

你只允許輸入以下數字 ,編寫一些組合語言來檢查它是否正常工作。

AND 1 0 1
CMP 0 0 1
BEQ label

嘗試編寫上述程式碼的 OR 版本。

移位操作

[edit | edit source]

如果你看一下以下數字的二進位制表示形式,你會注意到一些奇怪的地方。

0001 = 1
0010 = 2
0100 = 4
1000 = 8

每次我們將數字向左移動一位,數字的值就會加倍。這不僅適用於一位,看看這個更復雜的例子。

0001 0101 = 21
0010 1010 = 42

同樣,向左移動一位,數字就加倍了。另一方面,向右移動一位,數字就減半。

計算機在進行乘法和除法方面非常糟糕,它需要大量的 CPU 時間,並且會嚴重降低程式碼的速度。為了克服這個問題,計算機可以在暫存器中移動值,只要乘法或除法是 2 的冪,那麼 CPU 時間就會減少,因為操作只需要一行機器程式碼。處理器可以執行三種主要的移位型別。

邏輯移位

[edit | edit source]

向左或向右移動,你在空的一端新增一個 0。

算術移位

[edit | edit source]

你保留被移動數字的符號位。通常只向右移動

請注意,邏輯移位示例也是算術移位的示例,因為符號保持不變

迴圈移位

[edit | edit source]

被推到一端的那一位出現在另一端。

測試和分支指令

[編輯 | 編輯原始碼]

測試和分支指令用於測試給定條件是否為真,然後根據測試結果分支到給定指令。這使得條件語句和迴圈成為可能。

計算機指令

[編輯 | 編輯原始碼]

計算機理解稱為的指令。在計算環境中,字是指計算機一次可以執行的位數。你會遇到能夠理解不同字長大小的處理器,例如,索尼 PlayStation 上的處理器字長為 32 位。索尼決定讓 PlayStation 2 比初代產品更好,PlayStation 2 的字長為 128 位。一般來說,更大的字長意味著更快、更復雜的 CPU。

計算機能夠理解的字由兩部分組成。第一部分是指令型別,即操作碼,第二部分包含指令將要執行的變數,即運算元。運算元有時稱為地址,下一節將解釋計算機如何以不同的方式使用運算元。

0 地址指令

[編輯 | 編輯原始碼]

這種指令不接受任何引數,並涉及不需要變數的彙編程式碼。例如

  • CLC - 清除進位標誌
  • EXIT - 退出子程式
  • INC - 將累加器加 1

1 地址指令

[編輯 | 編輯原始碼]

當您只處理一個通用暫存器(累加器)時,這種指令非常有用,它只接受一個運算元。例如

  • LDA #34 - 將十進位制值 34 載入到累加器中
  • ADD 234 - 將儲存在記憶體地址 234 的值新增到累加器中

2 地址指令

[編輯 | 編輯原始碼]

這種指令可以接受兩個運算元,並且操作的複雜性也會增加。例如 ADD R1, R2 - 將 R1 加到 R2 並將結果儲存回 R1

定址格式

[編輯 | 編輯原始碼]

處理器可以使用不同的方法來計算正在處理的指令或正在操作的資料的記憶體地址。這些被稱為定址模式

立即定址

[編輯 | 編輯原始碼]

這是您迄今為止一直使用的定址模式,其中操作的資料在指令中給出。

例如:LDA #35; 將數字 35 立即載入到累加器中。

直接定址

[編輯 | 編輯原始碼]

在直接定址中,資料的地址將在指令中給出。

例如:LDA 35; 將地址 35 的內容載入到累加器中。

間接定址

[編輯 | 編輯原始碼]

這類似於直接定址,但是指令沒有給出資料的地址,而是給出儲存資料地址的地址。例如,如果記憶體地址 A0 包含“F1”,而記憶體地址 F1 包含“42”,那麼要將 42 載入到累加器中,指令將是

LDA (&A0); 將地址 &A0 中給出的內容載入到累加器中

相對定址

[編輯 | 編輯原始碼]

這種定址模式根據記憶體中的當前位置給出記憶體位置。

例如:JMP +10; 分支到距離當前指令 10 個位元組的指令。

如果此指令位於地址 1,則它將跳轉到地址 11。

基址暫存器定址

[編輯 | 編輯原始碼]

這種定址模式將指定的地址與另一個位置儲存的地址組合在一起。

LDA &12,B; 將 B 的內容與十六進位制地址 12 相加,並將結果地址的內容載入到累加器中。

在此示例中,地址 &12 將新增到 B 中儲存的地址,以找到要載入到累加器中的資料的地址。

索引定址

[編輯 | 編輯原始碼]

這種定址模式類似於基址暫存器定址,只是基址儲存在索引暫存器中。如果使用這種定址格式,則可以透過更改索引暫存器的內容來更改運算元的地址。

LDA TABLE,X; 將 TABLE + x 的內容載入到累加器中

一個幫你區分它們的故事

[編輯 | 編輯原始碼]

曾經有一個名叫累加器的匪徒,很酷的名字,對吧?他參與了許多“生意”,需要相應地得到報酬。他喜歡用幾種不同的方式獲得報酬。這些方式分別是立即、直接、間接、索引和相對。

當他立即得到報酬時,他的打手會當場給他錢,他無需去尋找或解開任何謎題,他就立即得到錢。

“老闆,這是 5 英鎊” =
“LDA #5”

當他直接得到報酬時,他需要做一些工作,他在整個城市都有很多郵箱,他的客戶會把付款丟在那裡。他會得到一個特定郵箱的名稱,並知道如果他去那裡,他就能找到他想要的現金。他被直接引導到現金。

“老闆,錢在地址 1023 的郵箱裡”。
= “LDA 1023”

你必須明白,累加器還有其他做一些不正當生意的朋友,他們更喜歡在商業交易中儘可能地隱藏自己,以避免警察的追查。為此,他們使用了一個巧妙的系統,將錢放入郵箱,但沒有直接告訴累加器地址,而是告訴累加器一個郵箱的地址,該郵箱包含真實郵箱的地址。他們間接地告訴了他地址。聽起來有點混亂?別擔心,希望這段簡短的文字可以解決問題。

“老闆,錢在哪裡的地址在地址 304 的郵箱裡”。
累加器開啟地址 304 的郵箱,發現一張紙條,上面寫著去 706。
當他到達 706 時,他找到了他想要找的錢。
= “LDA (304)”

對於一個匪徒來說,生意並不總是一帆風順,有時他們必須解開一個或兩個謎題才能拿到錢,就像電影裡一樣。在索引支付的情況下,累加器得到一個需要解決的線索,他知道基址,有人提供一個必須新增到基址的值。他將這兩個值加在一起,然後他就找到了他應得的錢的儲存地址。

“老闆,你需要的基址是 7987”。
“老闆,我們的訊息來源說,你錢存放的房子距離基址 5 個房子”。
累加器在 7987 + 5(7992)中找到了他想要找的現金。
= LDA TABLE,X

彙編程式碼

[編輯 | 編輯原始碼]

計算機只能理解 1 和 0。為了讓計算機理解我們想要它做什麼,我們必須將我們的想法轉化為這些 1 和 0。你可以使用高階語言或低階語言彙編。在彙編程式碼中,每一行程式碼通常會轉換成一行機器程式碼。彙編在工業中用於程式設計低階例程和函式,生成的程式碼通常簡單但很長。

指令集

[編輯 | 編輯原始碼]

指令集是 CPU 可以理解的不同指令的範圍。有兩種不同的思想流派,RISC 和 CISC。RISC - 精簡指令集計算機可以執行的指令數量很少,但它通常執行得非常快且高效。CISC - 複雜指令集計算機可以執行的指令數量很多,但通常不如執行等效 RISC 程式碼的速度快。

為了考試,你需要了解 CPU 可以理解的一些基本彙編指令。我們現在將看看一些指令的範圍,然後是一些使用它們的示例。

基本指令

[編輯 | 編輯原始碼]
ADD #34
將一個數字新增到累加器並存儲該值到累加器中
SUB #34
從累加器中減去一個數字並存儲該值回累加器中
DEC
從累加器中減去 1
INC
向累加器加 1
LDA 34
將記憶體位置 34 中包含的值載入到累加器中
STO 34
將累加器的值儲存到記憶體位置 34 中
CMP &34
將累加器與 34 的十六進位制值進行比較,並將結果儲存到狀態暫存器中
BNE label1
如果比較結果不等於,則跳轉到標籤 label1
BEQ label1
如果累加器與被比較的值匹配,則跳轉到標籤 label1
BGT label1
如果累加器大於被比較的值,則跳轉到標籤 label1
BLT label1
如果累加器小於被比較的值,則跳轉到標籤 label1
JMP label1
直接跳轉到標籤 label1,類似於某些高階語言中的 goto 函式
AND 01001001
對累加器與值 01001001 進行“與”運算,並將結果儲存到累加器中
OR 01001001
對累加器與值 01001001 進行“或”運算,並將結果儲存到累加器中
XOR 01001001
對累加器與值 01001001 進行“異或”運算,並將結果儲存到累加器中
對累加器進行“非”運算,並將結果儲存回累加器中
MOV R1, R2
將暫存器 R1 的內容移動到暫存器 R2 中

在此處新增移位指令

你可能已經注意到,上面的一些命令要求程式“跳轉”到名為 label1 的標籤。這執行與 C 等語言中的 'goto' 語句相同的函式。雖然 goto 語句在高階語言中被認為是不可取的,但在彙編中,它對於執行迴圈和條件語句是必不可少的。標籤在程式碼中將是這樣的

LDA #40
label1
INC
CMP #46
BLT label1
STO 1024

這段程式碼將值 40 載入到累加器中。然後累加器加 1 並與數字 46 進行比較。如果累加器 **小於** 46,則跳轉到標籤 label1 以繼續增加累加器。記憶體位置 1024 中將儲存什麼值?

在考試中,你經常會被要求取一段虛擬碼或真實程式碼並將其轉換為彙編程式碼。為了確保考官知道你在做什麼,請始終用程式碼編寫註釋。下面是一些虛擬碼及其彙編等效程式碼的示例

x = x + 1
LDA x
INC
INC
STO x
x = x + 1
while (x >= 6)
y = y + 4
end while
LDA x
while
LDA x
INC
INC
CMP #6
BLT end
LDA y
ADD #4

STO y

JMP while

end

快速檢查問題

[編輯 | 編輯原始碼]

提供將完成以下任務的彙編程式碼

y = x + y

計算給定二進位制數 x 的負二進位制補碼並將結果儲存回 x

將 ASCII 小寫字母更改為其二進位制等效值
Q3
[編輯 | 編輯原始碼]
執行 x= x-1
華夏公益教科書