Delphi标签的地址

时间:2012-05-24 14:18:32

标签: delphi delphi-2010

我正在使用Delphi pascal进行简单的PIC18 MCPU助记符模拟。是的,我打算使用Delphi IDE。 我能够模拟任何asm指令,但它会在标签处停止。 在某些情况下,我需要知道Delphi标签的地址。 是否有可能将标签转换为指针变量?

在我的例子中?

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;

// MCPU ASM代码的模拟

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;

1 个答案:

答案 0 :(得分: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的相对位置会发生变化,并且您最终会从堆栈中读取错误的值。