Re: [問題] 變數問題
因為應該會有其它人可能會碰到類似問題,
就直接回版上了, 這樣討論也比較方便.
簡單重覆你遇到的問題.
main() 中有段code
: test = 0;
: while(test<0x0130) {...}
而在isr()中會做
: ++test;
除此之外並無其它對test之讀寫.
遇到的問題是 while 迴圈"偶而"會在非預期的時候
(test的值明明還小於0x0130時)就跳出來.
※ 引述《ksmrt0123 (ksmrt)》之銘言:
: 下面有我disasemble的結果.
: test 是定義成unsigned int, 放在 data 0x08(MSB) 跟 0x09(LSB).
: 可看出 test<0x0130要由好幾個組合語言指令來完成.
: 你可想看看當test<0x0130做到一半,
: 若發生 RI interrupt,
: 是否有什麼狀況會造成你遇到的錯誤?
: 18: while(test<0x0130) {
: C:0x0012 C3 CLR C
: C:0x0013 E509 MOV A,0x09
: C:0x0015 9430 SUBB A,#0x30
: C:0x0017 E508 MOV A,test(0x08)
: C:0x0019 9401 SUBB A,#0x01
: C:0x001B 500A JNC C:0027
從反組譯的程式可看出, test是兩個byte的變數,
MSB放0x08, LSB放在0x09. 判斷 test<0x0130 是由
0x0015跟0x0019兩個SUBB組成, 經過這兩個SUBB若
C==0, 表示test<0x0130不成立, 就跳出迴圈(0x001B JNC ...).
會發生錯誤的情況是, 當test==0x00ff時, main()執行
上面那段code 執行到一半時
(0x0015的SUBB已執行完, 但0x0019的尚未執行),
發生interrupt, isr()因此會做 ++test, 故isr()
結束後 test的值是 0x0100.
51現在又回到main()繼續剛才未完成的工作.
執行到0x0019那個SUBB, 此時test的MSB的值已是0x01,
前一個SUBB(0xFF-0x30)也不會設定C, 所以運算結果C會是0,
就跳出迴圈了. 這就是你遇到的狀況.
這個問題最簡單的解決方法就是在計算 test<0x0130 時暫時
disable interrupt, 這樣 isr()就不會來插一腳造成錯誤.
但要disable interrupt以這段C code來說, 因為 test<0x0130
是embedded在while loop中, 所以從C直接加不太好加...
另有個相關的問題, main()中的 test = 0; 把test的值寫為0
需要分成至少兩個指令做, 那會不會有類似的狀況造成錯誤呢?
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 219.68.71.218
※ 編輯: ksmrt0123 來自: 219.68.71.218 (01/16 01:14)
※ 編輯: ksmrt0123 來自: 219.68.71.218 (01/16 11:50)
推
01/18 10:51, , 1F
01/18 10:51, 1F
推
01/18 13:45, , 2F
01/18 13:45, 2F
推
01/18 19:34, , 3F
01/18 19:34, 3F
→
01/21 21:11, , 4F
01/21 21:11, 4F
討論串 (同標題文章)
ASM 近期熱門文章
PTT數位生活區 即時熱門文章