2012-05-24 64 views
2

我正在使用Delphi pascal進行簡單的PIC18 MCPU助記符模擬。是的,我打算使用Delphi IDE。 我能夠模擬任何asm指令,但它停在標籤處。 在某些情況下,我需要知道Delphi標籤的地址。 有沒有可能將標籤投入指針變量?Delphi標籤的地址

正如我的例子? MCPU彙編代碼的

procedure addlw(const n:byte); //emulation of mcpu addlw instruction 
begin 
    Carry := (wreg + n) >= 256; 
    wreg := wreg + n; 
    Zero := wreg = 0; 
    inc(CpuCycles); 
end; 

procedure bnc(p: pointer); //emulation of mcpu bnc instruction 
asm 
    inc CpuCycles 
    cmp byte ptr Carry, 0 
    jnz @exit 
    pop eax  //restore return addres from stack 
    jmp p 
@exit: 
end; 

//仿真

procedure Test; 
label 
    Top; 
var 
    p: pointer; 
begin 
// 
Top: 
    addlw(5); //emulated mcpu addlw instruction 
    bnc(Top); //emulated mcpu bnc branch if not carry instruction 
// 
end; 
+2

我不確定我是否真的明白這一點。爲什麼你需要從同一例程中獲取標籤的地址? –

+1

看起來標籤的地址是它後面的指令的地址。我不認爲編譯器會引用它,它會在生成代碼的同時放置JMP,這就是全部。 –

+0

@David Heffernan:模仿goto asm intructions。 –

回答

5

不,你不能與標籤的方式進行交互。既然你是模擬其他所有的東西,你也可以模擬彙編標籤,而不是試圖強制Delphi標籤做一些他們沒有設計的東西。

假設你可以使用這樣的代碼,而不是你寫的「彙編」碼(不用擔心,現在究竟是如何實現它):

procedure Test; 
var 
    Top: TAsmLabel; 
begin 
// 
DefineLabel(Top); 
    addlw(5); //emulated mcpu addlw instruction 
    bnc(Top); //emulated mcpu bnc branch if not carry instruction 
// 
end; 

的語法看起來很相似,我認爲。運行該代碼後,您需要Top參考下一條指令,該指令稱爲addlw

裏面的假想功能DefineLabel,該地址對應於返回地址,所以寫DefineLabel來存儲它的返回地址在給定的參數:

type 
    TAsmLabel = Pointer; 

procedure DefineLabel(out Result: TAsmLabel); 
asm 
    mov ecx, [esp] // copy return address 
    mov [eax], ecx // store result 
end; 

要注意的是這個代碼破壞堆棧。您的bcn函數將其返回地址留在堆棧中,所以當進位標誌最終被設置時,您已經在堆棧上留下了先前返回地址的蹤跡。如果你沒有先獲得堆棧溢出,當你到達包含函數的結尾時,你會遇到奇怪的結果。它會嘗試返回,但不會轉到調用方,它會找到bnc的返回地址,並跳回到代碼中間。這一切都假設代碼中沒有任何其他堆棧相對引用。如果有,那麼即使調用bnc(Top)可能會產生問題,因爲Top的相對位置將發生變化,最終您將讀取堆棧中錯誤的值。

+0

是的,它看起來很喜歡唯一的方式!但是,如果我們不想在調用過程中使用標籤,問題就變成了。因此,我記得在第一次程序調用時啓動標籤,因此要添加所有程序,init標誌將在第一次調用時跳過實際的代碼執行並且僅啓動標籤。 –