2010-02-22 25 views
3

首先有一點背景。 z80 CPU有一條叫做DJNZ的指令,它可以以類似於for循環的方式使用。基本上,DJNZ遞減B寄存器並跳轉到標籤,如果不是零。例如:相當於其他架構上的Z80 DJNZ指令?

ld  b,96     ; erase all of the line 
disp_version_erase_loop: 
    call _vputblank    ; erase pixels at cursor (uses b reg) 
    djnz disp_version_erase_loop ; loop 

當然,你使用常規的比較和跳轉指令可以做同樣的事情,但往往是得心應手的單指令。

因此,我的問題是,其他CPU架構是否包含類似的控制指令?

回答

3

IA-32具有各種REP*指令使用CX作爲其計數器

1

存在着單指令集計算機,這是不實際使用。但是單個指令集機器之一是「如果小於或等於零的減法和分支」(subleq)機器。 Wikipedia has more on this

我不知道有任何其他真正的機器,但有一個像這樣的指令。我喜歡RISC機器,但實際上也沒有看到它的需要。

+0

這很有用,因爲循環計數器的測試不使用任何標誌。沒有必要混淆標誌是否用於循環中的某些東西/只有一組標誌/寄存器依賴管理不是很聰明(例如,POWER芯片只能爲條件寄存器重命名一次)。這個遞減對於普通情況來說只是一個方便的獎勵。 (例如,ARM只有比較分支如果爲零/非零位)(MIPS,作爲替代示例,沒有標誌寄存器,這是解決此類問題的另一種方法。) – 2010-05-03 21:07:01

1

的PDP-11(約公元前1970年)早於Z-80約5年,至少有一些模型(雖然可能不是早期的)有一個減去一和轉移指令:

sob R, offset 
2

的PowerPC具有bdnz和特殊的倒計時註冊ctr。減量ctr和條件分支與實際條件測試無關,因此您可以在bdnz之上添加條件,例如bdnzlt cr5, label(如果有內存服務)將檢查cr5中存儲的小於位以及AND ctr的條件變爲0.

具有諷刺意味的是,ctr也用於存儲任何間接函數調用目標。所以可以編寫指令「遞減ctr並分支到它的新值,如果不是零」,但這是特別禁止的。 (無論如何,它都不會檢查NULL指針。)有點顯然,bdnz在間接調用的循環中變得毫無用處。

6

對於DJNZ而言,IA-32直接等效的實際值爲LOOPcc(LOOPZ)。請記住Z80和8086的前身是Intel 8080。因此所有x86 CPU都直接繼承了DJNZ指令!

0

Z80是一個CISC處理器。 DJNZ是一個複雜指令的典型例子。現代時尚趨向於RISC指令集,它們喜歡更小,更簡單,更快的指令,但可以更快地處理它們 - 特別是使用先進的流水線功能。例如,我認爲你在ARM系列上沒有這樣的東西。

+0

CBZ/CBNZ ?這是它的一半。我的ARM雖然有點生鏽......但這可能不適用於所有模式? – 2010-05-03 21:13:45

1

在x86上,執行完全相同的操作的LOOP指令(使用ECX中的計數器)。還有JECXZ指令(如果ECX爲零,則跳轉)與LOOP一起使用 - 將其放在循環之前,以便在開始時計數爲零時跳過整個循環。

像這樣:

;number of iterations in ECX 
    JECXZ end 
start: 
    ;loop body 
    LOOP start 
end: 

但是請注意,這些指令是對當代CPU的效率極其低下。使用常規的CMP/SUB和Jcc指令要好得多。注意一點 - 英特爾Core2 CPU實際上可以將一個比較+跳轉指令對看作是一條單一指令 - 他們稱之爲「宏操作融合」。

2

某些PIC單片機(如PIC18)具有DECFSZ(遞減文件和跳過時爲零)指令。我經常放一個DECFSZ,然後是分支。