有這樣一個問題:
------------------------------
已知程序執行前有 A = 02H,SP = 52H,(51H) = FFH,(52H) = FFH。
執行下列程序:
POP DPH
POP DPL
MOV DPTR, #4000H
RL A
MOV B, A
MOVC A, @A + DPTR
PUSH A
MOV A, B
INC A
MOVC A, @A + DPTR
PUSH A
RET
ORG 4000H
DB 10H, 80H, 30H, 50H, 30H, 50H
求程序執行後:
A=( )H、SP=( )H、(51H) =( )H、(52H)=( )H、PC=( )H。
------------------------------
這個問題,在百度知道出現過很多次,搜一下,就會出來幾十個鏈接。
但是回答正確的,確實不多。
有的提問者,好像是說,這是什麼學校教材上的習題。
在這個程序中,寫錯了兩條指令:
非法指令:PUSH A
應該寫成:PUSH ACC
做爲教材來說,這可是一個 BUG 啊,呵呵
這個程序,是利用 RET 指令來進行多路分支。
程序中,有兩條查表指令:MOVC A, @A + DPTR,
當 A = 0 時,將從 4000H 處,先後讀出 10H、80H;
當 A = 1 時,將從 4000H 處,先後讀出 30H、50H;
當 A = 2 時,將從 4000H 處,先後讀出 30H、50H。
本題目的條件已經給出:A = 02H,那麼就是讀出了 30H、50H。
讀出數據後,先後壓棧,再執行 RET。
RET 指令,就是把堆棧中的兩個字節,送到 PC。
那麼,PC = 5030H,就是這麼來的。
全部的空格,填寫如下:
A=(50)H、SP=(50)H、(51H) =(30)H、(52H)=(50)H、PC=(5030)H。
------------------------------
本程序,是個子程序結構,應該用 CALL 指令來調用。
在本程序開始處,用 POP 指令,拋棄了 CALL 自動保存的返回地址。
騰出了兩個字節的堆棧空間,又壓入兩字節數據,然後,再返回。
RET 返回指令,就會用剛剛壓入兩字節數據,當做返回地址。
本程序,是屬於偷樑換柱,還是移花接木 ?
------------------------------
下面逐條解釋一下:
POP DPH
POP DPL ;彈出兩次,SP = SP - 2 = 50H
MOV DPTR, #4000H
RL A ;乘以2
MOV B, A ;B = 04H
MOVC A, @A + DPTR ;取出第4個字節30H
PUSH ACC ;SP = SP + 1 = 51H, (51H)=30H
MOV A, B
INC A ;A = 05H
MOVC A, @A + DPTR ;取出第5個字節50H
PUSH ACC ;SP = SP + 1 = 52H, (52H)=50H
RET ;子程序返回指令
執行 RET 指令時,是從堆棧中彈出兩個字節到 PC 的高、低八位。
即:
(SP) → PCH,然後 SP - 1 → SP;
(SP) → PCL,然後 SP - 1 → SP。
即:
(52H) = 50H → PCH,SP = 51H
(51H) = 30H → PCL,SP = 50H
那麼,PC = 5030H,就是這麼來的。
------------------------------
進行多路分支,還有簡單一點的方法。
如,利用指令:JMP @A + DPTR,就可以。
那麼,前面的程序,可以改爲:
MOV DPTR, #4000H
RL A
MOV B, A
MOVC A, @A + DPTR
XCH A, B
INC A
MOVC A, @A + DPTR ;先後讀出兩字節
MOV DPH, A ;把讀出數據送到 DPTR
MOV DPL, B
CLR A ;A=0
JMP @A + DPTR ;以 DPTR 內容爲目的地,轉移
ORG 4000H
DB 10H, 80H, 30H, 50H, 30H, 50H
程序這樣寫,就不涉及堆棧了,也就沒有前一個程序那麼複雜的推導。
理解起來,可以輕鬆些。
這個程序,沒有使用 RET 指令,那麼,就不要用 CALL 來調用了。
要用 JMP 指令來應用本程序。
------------------------------
題目鏈接:
http://zhidao.baidu.com/question/62813244.html
http://zhidao.baidu.com/question/508425830.html
http://zhidao.baidu.com/question/586060870.html
http://zhidao.baidu.com/question/205965529.html
------------------------------