我对Pascal了解并且无法理解这个汇编函数出了什么问题:
{$ASMMODE intel}
function SomeType.doSomething : boolean; assembler;
var i : integer; // for testing
asm
mov EAX, field
mov i, EAX // line 42
and EAX, 4
mov i, EAX
//...
end;
Run Code Online (Sandbox Code Playgroud)
课堂宣言:
type
SomeType = class(TObject)
private
field : integer;
function doSomething : boolean;
// ...
end;
Run Code Online (Sandbox Code Playgroud)
当field(一个类的字段SomeType)为4调用此方法之前,所述IDE(拉扎勒斯)将向我报告i在管线42分配8(参照线以上编号).
是否有关于内联装配的东西,我错过了?
为什么字段的值没有EAX正确存储和/或加载?
更新:我想我可能会瞄准64位.
读取对象的字段并不像从内存中读取普通内容那么简单.回想一下,成员访问是隐含的Self,所以当你field在代码中写入时,你真正的意思是Self.field.要从中读取值Self.field,编译器实际上需要用以下代码替换代码:
mov EAX, dword ptr [EAX + offset SomeType.field]
Run Code Online (Sandbox Code Playgroud)
您可以检查调试器中的CPU视图,看看是否真的发生了什么.
我想你会发现它不是.如果Free Pascal以与Delphi相同的方式解释此代码,那么裸引用field不包括隐式Self部分.相反,它只是该类中该字段的偏移量.是否field恰好是第二个数据成员在类中声明(包括任何祖先类中声明的任何东西)?如果是这样,那就解释了你从哪里获得8.VMT指针为0,第一个字段为4,依此类推,假设您没有大于4个字节,并且所有内容都对齐.
更改代码以从内存中读取值,就像上面的代码行一样.那种类型可能允许也可能不允许; 即你可能只是写offset field而不是offset SomeType.field.