# Assembly 期中上機考檢討 ## 1. (Part1) Assume a 32-bit word at memory address 0x40000000 contains 0xBEEFFACE. Write a program (including 5 independent steps below) to - (1) insert the value 0x8765 into the word so that the final value is 0xB8765ACE, - (2) set bits 5, 9, 13 and 17 of the word and leave the remaining bits unchanged, - (3) use one way to clear bits 7, 10, and 16 of the word and leave the remaining bits unchanged, - (4) use another way to clear bits 7, 10, and 16 of the word and leave the remaining bits unchanged, - (5) change bits 18, 25, and 26 of the word and leave the remaining bits unchanged. ### Solution Part1 - initital - 首先要將 `0x40000000` 這個記憶體位置存入 `0xBEEFFACE` 稱此為初始化。 ```asm= LDR r0, =0x40000000 LDR r1, =0xBEEFFACE STR r1, [r0] ``` - (1) - 接著先利用 **BIC** 清除 `r0` 所要插入的的位元接著在將 `0x8765` 插入至 `r0` 這個記憶體位置中。 - 其中 `ORR r9, r2, LSL #12` 要注意的是會先將 r2 轉換至 2進位制並且位移 12 位元在進行 OR 邏輯閘運算 (1 or 0 = 1)。 ```asm= LDR r9, [r0] LDR r2, =0x8765 LDR r3, =0xFFFF000 ; In order to BIC BIC r9, r3 ; clear bit that 0xBEEFFACE becomes 0xB0000ACE ORR r9, r2, LSL #12 ; STR r9, [r0] ``` - (2) - 設置分布在位元數 5, 9, 13, 17 的值,我們將它儲存在 `r4` 經計算可得知 `0010 0010 0010 0000` 轉換成16進位為 `0x22220` 。 ```asm= LDR r9, [r0] ; 1011 1110 1110 1111 1111 1010 1100 1110 LDR r4, =0x22220 ; 0010 0010 0010 0000 ORR r9, r4 ; 1011 1110 1110 1111 1111 1010 1110 1110 STR r9, [r0] ``` - (3) - 將目標暫存器的位元數 7, 10, 16 的值將其刪除。 ```asm= LDR r9, [r0] ; 1011 1110 1110 1111 1111 1010 1100 1110 LDR r5, =0x10480 ; 0001 0000 0100 1000 0000 BIC r9, r5 ; 1011 1110 1110 1110 1111 1010 0100 1110 STR r9, [r0] ; 0xBEEEFA4E ``` - (4) - 利用另一個方式來將 7, 10, 16 的值刪除 (0001 0000 0100 1000 0000)。 - `EOR r5, r7` 如果 r5 的值跟 r7 不一樣則該位元數更改為 1 一樣則該位元數變為 0 (ex: r5=1010 EOR r7=1000 = 0010)。 ```asm= LDR r9, [r0] ; 1111 1111 1010 1100 1110 LDR r5, =0x10480 ; 0001 0000 0100 1000 0000 LDR r7, =0xFFFFFFFF EOR r5, r7 ; 1110 1111 1110 0100 1110 AND r9, r5 ; 1110 1111 1010 STR r9, [r0] ``` - (5) - 改變位元數 18, 25, 26 的值(0110 0000 0100 0000 0000 0000 0000) - 利用 `EOR r9, r6` 來進行改變該數值。 ```asm= LDR r9, [r0] ; 1110 1110 1111 1111 1010 1100 1110 LDR r6, =0x6040000 ; 0110 0000 0100 0000 0000 0000 0000 EOR r9, r6 ; 1000 1110 1011 1111 1010 1100 1110 STR r9, [r0] ``` --- ## 2.(1) (Part1) Compute j = (2n + 2m - 2p) - 48 and put j in r5, assuming n = 7, m = 6 and p = 5 are respectively in r2, r3 and r4 initially. ### Solution Part1 - (1) - 利用位元位移 LSL 來快速達成取得 2^n 的值 - 2^7 + 2^6 - 2^5 - 48 = 112(0x70) ```asm= MOV r2, #7 ; n = 7 MOV r3, #6 ; m = 6 MOV r4, #5 ; p = 5 LDR r0, =1 ; 2^1 ADD r5, r0, LSL r2 ; 2^n ADD r5, r0, LSL r3 ; 2^n + 2^m SUB r5, r0, LSL r4 ; 2^n + 2^m - 2^p SUB r5, #48 ``` --- ## 2.(2) (Part2) Assume 0xDEADABCD, 0xABCD8765 and 0xBEEFFACE are respectively in memory at addresses 0x40000010, 0x40000020 and 0x40000030. Write a program to calculate - (a) the number of ones (using TST) in the word at address 0x40000010. - (b) the number of ones (using AND) in the word at address 0x40000020. - (c) the number of zeros (using TST and without using SUB) in the word at address 0x40000030 - (d) the number of different bits between the 2 words at addresses 0x40000020 and 0x40000030 > `leave the results of (a), (b), (c) and (d) respectively in the bytes at addresses 0x40000040, 0x40000044, 0x40000048 and 0x4000004C. (Note: Be sure to use loops.)` ### Solution Part2 - initial ```asm= LDR r0, =0xDEADABCD LDR r1, =0xABCD8765 LDR r2, =0xBEEFFACE LDR r3, =0x40000000 STR r0, [r3, #0x10] STR r1, [r3, #0x20] STR r2, [r3, #0x30] ``` - (a) - 計算有多少個 1 在 `0x40000010` (0xDEADABCD = 1101 1110 1010 1101 1010 1011 1100 1101)。並且要利用 `TST` 指令來達成。 - 利用 `label` 達成迴圈效果,並且一一確認位元是否為 1 (`TST r7, r4`) - 而此迴圈總共會執行 32 次 (因為是32位元) - 計算後得知總共會有 21 個 1 ```asm= LDR r4, =1 LDR r5, =0 LDR r6, =32 LDR r7, [r3, #0x10] LOOPa TST r7, r4 ADDNE r5, #1 LSL r4, #1 SUB r6, #1 CMP r6, #0 BNE LOOPa STR r5, [r3, #0x40] ``` - (b) - 計算有多少個 1 在 `0x40000020` (0xABCD8765 = 1010 1011 1100 1101 1000 0111 0110 0101),並且要利用 `AND` 指令來達成。 - 利用 `label` 達成迴圈效果,並且一一確認位元是否為 1 (`AND r8, r7, r4`) - 而此迴圈總共會執行 32 次 (因為是32位元) - 計算後得知總共會有 18 個 1 ```asm= LDR r4, =1 LDR r5, =0 LDR r6, =32 LDR r7, [r3, #0x20] LOOPb AND r8, r7, r4 CMP r8, #1 ADDEQ r5, #1 LSR r7, #1 SUB r6, #1 CMP r6, #0 BNE LOOPb STR r5, [r3, #0x44] ``` - (c) - 計算有多少個 0 在 `0x40000030` (0xBEEFFACE = 1011 1110 1110 1111 1111 1010 1100 1110),並且要利用 `TST` 指令來達成。 - 利用 `label` 達成迴圈效果,並且一一確認位元是否為 1 (`TST, r7, r4`) - 而此迴圈總共會執行 32 次 (因為是32位元) - 因為 `TST` 是判斷是否為 1,則我們使用 32 位元的特性,從 32 開始扣出現 1 的位元 - 計算後得知總共會有 8 個 0 ```asm= LDR r4, =1 LDR r5, =0 LDR r6, =0 LDR r7, [r3, #0x30] LOOPc TST r7, r4 ADDEQ r5, #1 LSL r4, #1 ADD r6, #1 CMP r6, #32 BNE LOOPc STR r5, [r3, #0x48] ``` - (d) - 計算有多少個不同數值的位元數並且將其加總 - 計算後得知總共會有 16 個相異的值 ```asm= LDR r4, =1 LDR r5, =0 LDR r6, =32 LDR r7, [r3, #0x20] LDR r8, [r3, #0x30] EOR r9, r7, r8 LOOPd TST r9, r4 ADDNE r5, #1 LSL r4, #1 SUB r6, #1 CMP r6, #0 BNE LOOPd STR r5, [r3, #0x4C] ``` --- ## 3. (Part1) Write a program to declare the following variables. ```asm= data1 DCB “Midterm Exam in Fall 2023!”, 0 data2 DCW 0x1234, 0x5678, 0xBEEF, 0xFACE data3 DCD 0x8ECC, 0xFE37, 0xABCD, 1, 5, 0x1234FACE data4 DCB 0xCF, 23, 39, 0x54, 250, 0xFF, 0xAD data5 DCD 0xFE37, 1, 5, 20, 0xABCDFACE, 0x12345678 ``` - (1) Point out each stored value from the memory window and write down the address of each variable (data1~data5). (Be sure to use loops in Problems (2)~(9) below.) - (2) Store data1 into memory started from address 0x40000000. - (3) Reverse the string in data1 and put the reversed string in the memory started at address 0x40000030. - (4) Store data2 into memory started from address 0x40000060. - (5) Store data3 into memory started from address 0x40000070. - (6) Reverse data3 and put the reversed data3 in the memory started from address 0x40000090. - (7) Store the string data4 into memory started from address 0x400000B0. - (8) Store data5 into memory started from address 0x400000C0 - (9) Add the 6 words in data5 and put the sum in the word at memory address 0x400000E0. ### Solution Part2 - (1) - 利用 ADR 將 data 存入記憶體裡面。 - `ADR r1, data1` 將 data1 的地址載入到寄存器 r1 中 ```asm= ADR r1, data1 ADR r2, data2 ADR r3, data3 ADR r4, data4 ADR r5, data5 ``` - (2) - 讀取 data1 的資料並將其儲存置 `0x40000000` - 判斷當前的記憶體位置的值是否為0,如果為0則跳出迴圈 - 因為題目說要用迴圈來讀取資料所以不能直接儲存資料 ```asm= ADR r1, data1 LDR r0, =0x40000000 LOOP2 LDRB r6, [r1], #1 STRB r6, [r0], #1 CMP r6, #0 BNE LOOP2 ``` - (3) - 讀取 data1 的資料並將其儲存置 `0x4000030` - 並且要以反向的方式來讀取必須從最後一個位元開始讀 - 所以我們先將位置跳到最後一個位元,再來讀取資料 ```asm= ADR r1, data2 LDR r0, =0x40000030 ADD r0, #25 LOOP3 LDRB r6, [r1], #1 CMP r6, #0 STRBNE r6, [r0], #-1 BNE LOOP3 ``` - (4) - 讀取 data2 的資料並將其儲存置 `0x40000060` ```asm= ADR r1, data2 LDR r0, =0x40000060 LDR r3, =4 LOOP4 LDRH r6, [r2], #2 STRH r6, [r0], #2 SUB r3, #1 CMP r3, #0 BNE LOOP4 ``` - (5) - 讀取 data3 的資料並將其儲存置 `0x40000070` ```asm= ADR r1, data3 LDR r0, =0x40000070 LDR r3, =6 LOOP5 LDR r6, [r1], #4 STR r6, [r0], #4 SUB r3, #1 CMP r3, #0 BNE LOOP5 ``` - (6) - 讀取 data3 的資料並將其儲存置 `0x4000090` - 並且要以反向的方式來讀取必須從最後一個位元開始讀 - 所以我們先將位置跳到最後一個位元,再來讀取資料 ```asm= ADR r1, data3 LDR r0, =0x40000090 ADD r0, #20 LDR r3, =6 LOOP6 LDR r6, [r1], #4 STR r6, [r0], #-4 SUB r3, #1 CMP r3, #0 BNE LOOP6 ``` - (7) - 讀取 data4 的資料並將其儲存置 `0x400000B0` ```asm= ADR r1, data4 LDR r0, =0x400000B0 LDR r3, =7 LOOP7 LDRB r6, [r1], #1 STRB r6, [r0], #1 SUB r3, #1 CMP r3, #0 BNE LOOP7 ``` - (8) - 讀取 data5 的資料並將其儲存置 `0x400000C0` ```asm= ADR r1, data5 LDR r0, =0x400000C0 LDR r3, =6 LOOP8 LDR r6, [r1], #4 STR r6, [r0], #4 SUB r3, #1 CMP r3, #0 BNE LOOP8 ``` - (9) - 將 data5 中的 6 個字相加,並將和放入記憶體位址 `0x400000E0` 的字中 ```asm= ADR r1, data5 LDR r0, =0x400000E0 LDR r3, =6 LDR r7, =0 LOOP9 LDR r6, [r1], #4 ADD r7, r6 SUB r3, #1 CMP r3, #0 BNE LOOP9 STR r7, [r0] ``` --- >Note: (1) put necessary Keil Tool DEBUG window screenshots to show your program and execution results including highlighted necessary initial assumptions and subsequent memory and register changes, (2) comment student ID+your English name in every screenshots, and (3) put reports into one word file named by student_ID+your_name.