天天看點

【西電微電子計算機組成原理】lc-3 上機題:機器碼求和并輸出十六進制

問題一:12個整數求和的實作:

要求:将寄存器累加值送到控制台進行顯示,顯示方式采用16進制即可,并給出顯示截圖;

題目來自康老師檔案,以及作業要求是機器碼,彙編碼的是下一次上機

實作求和

提示:這裡描述項目中遇到的問題:

這個是題目給的代碼,,

0011 000000000000 ; Start at x3000
1110 001011111111 ; R1 x3100 (PC+0xFF)
0101 011011100000 ; R3 0
0101 010010100000 ; R2 0
0001 010010101100 ; R2 12
0000 010000000101 ;若 Z, 轉到 x300A (PC+5)
0110 100001000000 ; 将下個數字加載到 R4
0001 011011000100 ;加到 R3= R3+R4
0001 001001100001 ; R1累加 (指針)
0001 010010111111 ; R2減一 (計數器)
0000 111111111010 ;轉到 x3004 (PC-6)
           
如果不需要輸出直接到這裡就行

實作十六進制輸出

求和:

0011 000000000000 ; Start at x3000
1110 001011111111 ; R1 x3100 (PC+0xFF)
0101 011 011 1 00000 ; R3 0
0101 010 010 1 00000 ; R2 0
0101 000 000 1 00000 ; R0 0
0001 010010101100 ; R2 12
0000 010 000000110 ;若 Z, 轉到(PC+6)
0110 100 001 000000 ; 将下個數字加載到 R4
0001 011 011 000100 ;加到 R3= R3+R4
0101 000 000 1 00000 ; R0 0
0001 001 001 100001 ; R1累加 (指針)
0001 010 010 111111 ; R2減一 (計數器)
0000 111 111111001 ;轉到(PC-7)
0001 000 011 000000;将r3給到r0 因為輸出指令trap x21是輸出r0的,得把結果給到r0;
;轉十六進制位址
0000 111 001000001 ;3050,at300d pc+1000001 這裡改改,十六進制檔案執行位址在x3050,這裡直接跳轉過去。
           

十六進制:

大概就是減去16,然後取餘數,進位的再同理取餘;以及加個判斷是否為0的條件會簡化運作

0011 000001010000 ; Start at x3050
;initialize
0101 001 001 1 00000 ;r1 0 (十位
0101 010 010 1 00000 ;r2 0 (百位
0101 011 011 1 00000 ;r3 0 (千位
0101 100 100 1 00000 ;r4 0 (個位
0101 101 101 1 00000 ;r5 0
0101 110 110 1 00000 ; R6 0 (判斷用
0101 111 111 1 00000 ; R7 0
;first 
0001 000 000 1 00000 ; R0 r0   [001
;0000 010 000001111;if z ,turn to next pc+15
0000 100 000000011;若n,轉(pc+3
0001 000 000 1 10000;r0=r0-16
0001 001 001 1 00001;r1++
0000 111 111111011;turn to pc-5
0001 000 000 1 01111;r0=r0+16 [001
0001 000 000 1 00001;
0001 001 001 111111;r1=r1-1
;digit or alphabet 就是字母A(10)的ascii和數字的是不一樣的嘛,判斷一下轉去加上數字得到對應ascii就能輸出
;0001 110 000 1 00000 ;r6 r0
0001 110 000 1 10111 ;r6=r6-9
0000 100 000000101;if n,r0+48 turn to pc+5;if pz,r0+55
0001 000 000 1 01111;r0+55 這裡當時上機還不會别的代碼,直接+15+15+15+10來實作的;之後的也是笨方法,如果會asm來寫就簡單很多
0001 000 000 1 01111
0001 000 000 1 01111
0001 000 000 1 01010
0000 111 000000100;turn to pc+3
0001 000 000 1 01111;r0+48
0001 000 000 1 01111
0001 000 000 1 01111
0001 000 000 1 00011
0001 100 000 1 00000 ;r4 r0 store 各位
;接下來的也是差不多,複制粘貼改改寄存器的代号就行
;second
0001 001 001 1 00000 ; R1 r1   [001
0000 010 000001110;if z ,turn to next 
0000 100 000000011;若n,轉(pc+3
0001 001 001 1 10000;r1=r1-16
0001 010 010 1 00001;r2++
0000 111 111111010;turn to pc-6
0001 001 001 1 01111;r1=r1+16 [001
0001 001 001 1 00001;
0001 010 010 1 11111;r2=r2-1
;digit or alphabet
0001 110 001 1 10111 ;r6=r1-9
0000 100 000000101;if n,r1+48 turn to pc+5
0001 001 001 1 01111;r0+55
0001 001 001 1 01111
0001 001 001 1 01111
0001 001 001 1 01010
0000 111 000000100;turn to pc+3
0001 001 001 1 01111;r1+48
0001 001 001 1 01111
0001 001 001 1 01111
0001 001 001 1 00011
;下面的代碼注釋就亂了别看注釋
;third
0001 010 010 1 00000 ; r2   [001
0000 010 000001110;if z ,turn to next 
0000 100 000000011;若n,轉(pc+3
0001 010 010 1 10000;
0001 011 011 1 00001;
0000 111 111111010;turn to pc-6
0001 010 010 1 01111;r1=r1+16 [001
0001 010 010 1 00001;
0001 011 011 1 11111;r2=r2-1
;digit or alphabet
0001 110 010 1 10111 ;r6=r1-9
0000 100 000000101;if n,r1+48 turn to pc+5
0001 010 010 1 01111;r0+55
0001 010 010 1 01111
0001 010 010 1 01111
0001 010 010 1 01010
0000 111 000000100;turn to pc+3
0001 010 010 1 01111;r1+48
0001 010 010 1 01111
0001 010 010 1 01111
0001 010 010 1 00011
;這裡改個跳轉加的偏移碼,因為它沒有進位了
;forth
0001 011 011 1 00000 ; r3  [001
0000 010 000001100;if z ,turn to next 
0000 100 000000010;若n,轉(pc+2
0001 011 011 1 10000;r1=r1-16
0000 111 111111011;turn to pc-5
0001 011 011 1 01111;r1=r1+16 [001
0001 011 011 1 00001;
;0001 010 010 1 11111;r2=r2-1
;digit or alphabet
0001 110 011 1 10111 ;r6=r1-9
0000 100 000000101;if n,r1+48 turn to pc+5
0001 011 011 1 01111;r0+55
0001 011 011 1 01111
0001 011 011 1 01111
0001 011 011 1 01010
0000 111 000000100;turn to pc+3
0001 011 011 1 01111;r1+48
0001 011 011 1 01111
0001 011 011 1 01111
0001 011 011 1 00011

;output分别從高位到低位輸出
0001 000 011 1 00000 
1111 0000 001 00001;output r0
0001 000 010 1 00000 
1111 0000 001 00001;output r0
0001 000 001 1 00000 
1111 0000 001 00001;output r0
0001 000 100 1 00000 
1111 0000 001 00001;output r0

1111 0000 00100101;halt
           

然後注意nzp判斷是基于上一個寄存器存入的内容就行了。

以及自己寫的檔案可以自己加上字尾這樣編輯器就可以直接打開了,就不用每次都複制粘貼;比如你寫的二進制就加.bin;十六進制加.hex;彙編寫的加.asm。

這裡附上測試資料:

3100 ;start at x3100
0001
0002
0003
0004
0005
0006
0007
0008
0009
000a
000b
000c`
           

問題三:5.5例子:字元數統計

課本也有,就是黑黃皮那本,計算機系統概論;主要還是要求的十六進制輸出,是以之前寫的就一勞永逸,跳到十六進制檔案位址輸出就行。

0011 000000000000   ;start at 3000
0101 010 010 100000 ;初始化
0010 011 000010000  ;x3012的内容位址導入r3
1111 0000 00100011  ;input
0110 001 011000000  ;r1=r3
0001 100 001 111100 ;eot?就是判斷結束符0004
0000 010 000001000  ;if z,output
1001 001 001 111111 ;-r1
0001 001 001 100001 ;r1+1
0001 001 001 000000 ;r1=r1+r0
0000 101 000000001  ;ifnp,pc+1
0001 010 010 100001 ;r2++
0001 011 011 100001 ;r3++
0110 001 011 000000 ;r1=r3
0000 111 111110110  ;pc-10
0010 000 000000100  ;
0001 000 000 000010 ;r0=r0+r2
0000 111 000111111;轉16進制(上邊提到了)入口3050 x3010 pc+11 1111 
1111 0000 00100101  ;halt在這加斷點單步看
0011 000100000000;3100,at x3012
           

測試資料:

3100;start
;都是大寫字母,與小寫區分(但題目沒說是否區分大小寫
0041;A
0042;B
0043;
0044;
0045;
0041;
0041;
0043;
0047;
0004;eot
           

好的到這就結束了,啥啥指令跳轉的繞暈了小破站有個視訊講的挺好的。

繼續閱讀