LC-3学习记录(一)
啥是LC-3?
LC-3是一種簡單(可能?)的十六位機器語言,它具有沒什么卵用且可能使您掛科的作用。該語言自發明以來飽受歡迎,它受歡迎就體現在它受歡迎個錘子的歡迎,內網外網啥資料找不到它受歡迎它受了個蔡徐坤的歡迎(全惱)。
不知道為啥奧大的計組要我們學這種冷門匯編(可能是因為好上手?希望他們是這么想的罷…)…感覺相關的資源都很少,不會的地方也找不到人問,學起來太痛苦了。思前想后,這門匯編內容上其實真的不難,覺得要是后來人學起這個因為資源缺乏再遭罪實在不值得,故撰此文,希望能幫大家省去一些被知識的海洋倒灌的時間和精力。
注:本文假設您已經具有基本的計算機組成原理的知識基礎,即理解基本的二進制運算、機器語言、寄存器、內存尋址的常識。
二注:本文主要是給小白看的,講得可能特別啰嗦(明明就是因為我這人本來就比較啰嗦x )
この分割線だ
LC-3的基本指令結構和語法
LC-3是儲存在內存中的指令集合,其由十六位二進制數組成,按照內存地址的順序運行,通過讀寫寄存器并將值存入內存的方式運作。LC-3假設有從R0到R7的8個可調用的寄存器。
所有LC-3指令都符合 前4位為操作碼,后12位為操作數的結構。對于不同的操作碼的操作,后12位的操作數的具體結構不同。
一行LC-3指令大概長這樣:
操作碼 操作數 0000 000000000000如果想在這行執行不同的指令,就需要在這行儲存不同的操作碼。
比如,假如我們要在這一行LC-3機器碼中,對寄存器R1中的數+1。
我們首先找到加法操作的語法:
ADD的操作碼是0001。當LC-3計算機發現這行代碼由0001打頭時,就會把后面的部分當作ADD操作的操作數。
Dst指儲存加法運算結果的寄存器。
Src1指儲存運算加法的一個加數的寄存器。
Imm5指要加的值
因此,我們想要的指令就為:
0001 001 001 1 00001其等價于
R1 = R1 + 1;0001告訴計算機我們進行的是加法運算(即格式為「Dst = Src1 + Imm5;」的運算),而不是別的。
001指計算的值要儲存在R1寄存器中,只有被指定的寄存器才會發生改變。也就是說如果這里指定的是010(R2寄存器),那么經管你取出的是R1的值進行的運算,R1也不會發生改變。
就好比:
變的是R2,R1是不變的。(我是不是講太細了x)
第二個001指取出R1中的值作為加數。
1指后面的加數為常量,如果這里為0,后面的加數就不是一個二進制常量,而會被當成一個寄存器了。
00001指加數常量。
加數有兩種形式
Dst = Src1 + Imm5;只是其中一種,還有一種為
Dst = Src1 + Src2;機器語言的語法格式為
可以看見,二者的主要差別在于從右數的第五位數。如果計算機讀到這行指令由0001開頭,就會再讀右數第五位數,如果為1則把最后五位數作為常數,如果為0則把最后三位數作為寄存器。
例:
R2 = R1 + R3;可表述為LC-3指令:
0001 010 001 0 00011看到這這行應該用不著多解釋了罷~
LC-3的主要指令
LC-3有著豐富(個錘子 )且強大(個屁 )的指令集。
主要包括:
操作指令:ADD, AND, NOT
數據遷移指令:LD, LDI, ST, STI, STR, LDR, LEA
程序控制指令:BR, JMP, RTI, TRAP, JSR/JSRR
操作指令
ADD
AND
對Src1寄存器中的每一位與Src2或一個常數中對應的每一位進行二進制 和操作,并存入Dst寄存器。
NOT
對Src1寄存器中的每一位進行二進制非操作,并存入Dst寄存器。
數據遷移指令
LD
將內存中的內容存入Dst寄存器。PCoffset9指PC偏移量。
PC就是現在的指令所在的內存地址,offset指偏移量,⑨指笨蛋 ,9指占用9位二進制數。
意思就是把PC + offset9那個位置的代碼放到指定的Dst寄存器里頭。
比如,假如我們現在的代碼在的地址是3000(PC = 3000),
0010 010 000001111這行代碼就意味著 把地址為3015(3000 + 15)處的內容存進R2中。
LDI(花里胡哨的)
LDI比LD復雜一點。它要多套一個娃。
LD是直接找到PC+offset的內容,然后指把這個內容搬進Dst。LDI要多一步,它先找到PC+offset,然后把PC+offset的值作為地址,再尋一遍址,然后把這個地址的內容存進Dst。(我就感覺到繞)
比如,還是用前面的例子,我們把LD簡單改成LDI。
1010 010 000001111這行代碼就意味著 把地址為3015(3000 + 15)處的內容作為地址 把這個地址的內容 存進R2中。
假如3015的內容是1500,那么R2的值就會變成地址為1500的儲存器的值。
ST
ST是LD的逆操作,它將寄存器Src中的值存入PCoffset中的內存空間。
LD是把內存中的內容拿進寄存器,ST反過來,把寄存器的內容拿進內存。
STI
同理,STI是LDI的逆操作,把寄存器的指取出來,放進PCoffset的地址的內容指定的地址里去。
LDR(更加花里胡哨的)
Base其實就是一個寄存器。LDR要做的就是把base寄存器中的內容取出來作為地址,找到這個地址后,給它加上offset偏移值,然后把這個地址中的內容存進Dst寄存器。
比如,假如R2中的值為1919,地址為1926的內存空間中存的值為1145,
0110 001 010 000111這串代碼指的就是把Base中的值(1919)取出來,加上7(變成1926),然后我們以之為地址,找到1926,并把里面的值存入Dst(R1)。然后R1就變成了1145了。
STR
我覺得任何一只貓咪都能輕而易舉地猜到這肯定是LDR是逆操作。
前面的步驟不變,把最后一步反過來(內存中的值存進寄存器變成寄存器中的值存進內存)即可。
LEA(好!很直接!)
LEA沒有任何尋址,它僅僅只是把PC+offset的地址的值存進寄存器Dst。非常得友好,非常得好理解。事鑒語句。
程序控制指令
BR
這個屑指令tlld我課件沒看懂百度谷歌查了好長時間都沒找到相關的起碼折騰了我兩三個小時氣死我學tnd屑指令wdnmd
(冷靜下來)BR指令是LC-3中最基礎的跳轉指令,作用類似于高級語言中的while、 for等循環語句(也可以當if用),但是理解起來不那么容易。
這里推薦大家可以移步嗶哩嗶哩大學參考一下這個灣灣做的視頻:
BR語句的基本格式如下:
nzp類似于高級語言中的判斷表達式(就是C、java里的while語句中圓括號里的東西),n是negative的意思,意味著判斷上一個操作的寄存器的值是否小于零,z是zero的意思,意味著判斷上一個操作的寄存器的值是否等于零,p是positive的意思,意味著判斷上一個操作的寄存器的值是否大于零。
什么?你問我計算機怎么判斷上一個操作過的寄存器的正負值?專門取出來判斷一遍嗎?我本來也納悶這個,后來我才知道LC-3的計算機里頭專門有三個bit存上一個寄存器的值(這個我查了老半天(怨))。
LC-3的計算機中每進行一次寄存器操作,LC-3就會記錄這個寄存器的正負值,并存在那三個bit中。比如我把-1賦值給R1,LC-3中記錄nzp的值的那三個bit就會變成100(n為1,指這個值是負數)(不可能出現110這樣的,沒有數既是負數又是0)。
而語句中的nzp則用于判斷LC-3中的記錄nzp的三個bit中的值是否符合語句中的nzp。
比如,語句中的nzp為010,這的含義就是「假如上一個被操作過的寄存器的值為0,我就把PC (現在的執行的指令的地址)設為PC+offset,否則繼續按正常順序執行指令」。
可以理解為while (Rx(上一個被操作的寄存器) == 0) {}這樣的語句。
如果語句中的nzp為110,就可以理解為while (Rx(上一個被操作的寄存器) <= 0) {}這樣的語句。
如果為111,則相當于必然跳轉。
總結:BR語句的含義就是,如果上一個操作過的寄存器的值符合指令中的nzp的條件,則對現有的PC進行跳轉,否則繼續執行下一個指令。
一般BR在使用時有兩種用法。
一個是循環的實現。
在BR前面放一個寄存器運算指令。比如R1 = R1 - 1;這樣的。然后在一開始設定R1位某個特定正數值,把br語句的nzp設定為001(若R1>0)或者011(若R1>=0),則將PC跳轉至之前的某一個位置(offset為負數),也就是說重新執行一遍前面的一段指令。然后R1不斷減一,直到為零或者小于零。這就是while和for的匯編底層實現。
另一個是條件分支判斷,即if的實現。
和之前不同的地方在于嗎,如果要實現if,offset值一般設定為正數,即假如符合條件,就跳過一段指令(不執行),不符合就執行這段指令。
(如果還沒看明白可以私聊我orz,我語音+畫圖可能理解更清晰一些orz)
JMP
覺得BR用起來麻煩?學著糟心?看著頭大?來用JMP罷!你用不了上當用不了吃虧…
JMP語法很簡單,啥條件判斷妹有,說跳就跳(無條件跳轉),想跳哪就跳哪(與BR使用偏移量跳轉不同,它使用的是直接尋址)。
JMP會讀取Base寄存器中的數值作為地址,然后直接把PC置為該地址,簡單粗暴直接,事鑒語句(確信)。
RTI(這個好像叫RET,沒搞懂到底叫啥)
比JMP更加簡單粗暴,直接指定一個常數作為地址,然后把PC設為這個地址。
格式: 1100 + 十二位常數。
TRAP
t rap,是一種rap ,是trapvector的縮寫,意為陷阱矢量。
它會先把現在的PC + 1的值給R7,然后把trapvector8中的值作為PC。
我其實不是很明白有明白的可以來教我一下,…
JSR/JSRR
JSR看起來就是把PC + 1交給R7,然后PC加上常量offset偏移值。(不是很理解這是在干啥x)
JSRR也很粗暴,也是把PC + 1交給R7,然后PC變為Base寄存器中的值。
我在想假如Base寄存器指定為R7會咋樣()。(可能會直接執行下一行罷)
碼了一上午了有點累,也權當給自己復習復習。偽代碼和網絡編程的內容咱自己也有一些不明白,所以放到后面寫罷orz,到時候整點例題來給大家看看
大家如果有什么問題或者建議可以加咱的QQ306168645來交流。來閑聊也星233333,咱超話癆的,雖說咱未必有時間orz
大家學習順利愉快w
總結
以上是生活随笔為你收集整理的LC-3学习记录(一)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python 爬虫斗图吧 多页图片
- 下一篇: ESP32|基于ESP32制作的低成本、