This is the hw02 sample. Please follow the steps below.
-
Fork this repo to your own github account.
-
Clone the repo that you just forked.
-
Under the hw02 dir, use:
-
make
to build. -
make clean
to clean the ouput files.
-
-
Extract
gnu-mcu-eclipse-qemu.zip
into hw02 dir. Under the path of hw02, start emulation withmake qemu
.See Lecture 02 ─ Emulation with QEMU for more details.
-
The sample is designed to help you to distinguish the main difference between the
b
and thebl
instructions.See ESEmbedded_HW02_Example for knowing how to do the observation and how to use markdown for taking notes.
-
Edit main.s.
-
Make and run like the steps above.
-
Please modify main.s to observe the
push
and thepop
instructions:Does the order of the registers in the
push
and thepop
instructions affect the excution results?For example, will
push {r0, r1, r2}
andpush {r2, r0, r1}
act in the same way?Which register will be pushed into the stack first?
-
You have to state how you designed the observation (code), and how you performed it.
Just like how ESEmbedded_HW02_Example did.
-
If there are any official data that define the rules, you can also use them as references.
-
Push your repo to your github. (Use .gitignore to exclude the output files like object files or executable files and the qemu bin folder)
- If you volunteer to give the presentation next week, check this.
Please take your note here.
- 先將資料夾 gnu-mcu-eclipse-qemu 複製到 ESEmbedded_HW02 資料夾中
- 設計測試程式 main.s ,從 _start 開始後依序執行 push 以及 pop 並且觀察其指令差異, 目標比較 18 行的
push {r0, r1, r2}
以及 20 行的push {r2, r0, r1}
執行時的變化。
main.s:
_start:
nop
//mov
mov r0, #100
mov r1, #0x11000000
mov r2, #102
mov r3, #103
//push
push {r0, r1, r2}
pop {r2}
push {r2, r0, r1}
pop {r0}
label01:
nop
//
//branch w/ link
//
bl sleep
sleep:
nop
b .
- 將 main.s 編譯並以 qemu 模擬, 先
$ make clean
, 再$ make
,$ make qemu
完開啟另一 Terminal 連線$ arm-none-eabi-gdb
,再輸入target remote 127.0.0.1:1234
連接,輸入兩次的 ctrl + x 再輸入 2或是輸入layout regs
, 開啟 Register 以及指令,並且輸入display $sp
接著再輸入si
單步執行觀察。 當執行完push {r0, r1, r2}
時, pc 跳轉從 0x1a 至 0x1c 且 sp 從0x20000100
至0x200000f4
。
當執行到pop{r2}
時,pc 跳轉從 0x1c 至 0x1e 且 sp 從 0x200000f4
至 0x200000f8
。
當執行到main.s中第20行的push{r2, r0, r1}
時,此時gdb顯示為push {r0, r1, r2}
,代表前兩者表示是相同會依照數字大小排序。而 pc 跳轉從 0x1e 至 0x20 且 sp 從 0x200000f8
至 0x200000ec
。
當執行到pop{r0}
時,pc 跳轉從 0x20 至 0x22 且 sp 從 0x200000ec
至 0x200000f0
。
- 結果與討論
(1)For example, will push {r0, r1, r2} and push {r2, r0, r1} act in the same way?Ans:兩者都會先將數字小的r0放入stack,再依序將r1,r2放入。
(2)push一個register,會使sp減少4bytes;反之pop一個register,會使sp增加4bytes。
如push {r0, r1, r2},sp從0x20000100=>256
至 0x200000f4=>244
(即減少12bytes)。
如pop {r2},sp從0x200000f4=>244
至 0x200000f8=>248
(即增加4bytes)。