You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Delphi 7内联汇编中如何访问VAR参数记录的字段?

Delphi 7内联汇编访问VAR参数记录字段的正确方式

你的问题核心出在两个地方:VAR参数的指针处理错误,以及字段偏移的引用方式不对。

错误分析

  1. VAR参数的指针误用:
    声明var _rec: TMyRecord时,_rec在栈中存储的是传入变量的地址(即recMyRecord的首地址)。你代码里的Mov EBX,[EBX]是多余的——这一步把EBX从记录首地址变成了记录第一个字段Name的内容(Name是string类型,占4字节指针),导致后续所有地址计算都基于字符串内存而非记录内存,必然崩溃。

  2. 字段偏移的引用错误:
    汇编中直接写_rec.age时,Delphi编译器会将其解析为栈上参数_rec的位置加上Age字段的偏移,而不是你期望的“记录首地址+字段偏移”。正确的字段偏移应该基于记录类型本身,用offset TMyRecord.Age来获取。

修正后的代码

program compile;

{$APPTYPE CONSOLE}

uses
  SysUtils;

type
  TMyRecord = record
    Name : string;
    Age  : word;
    Sex  : char;
  end;
var
  recMyRecord : TMyRecord;

procedure Test(var _rec: TMyRecord);
begin
  ASM
    Mov EBX, _rec                     // EBX = recMyRecord的首地址(VAR参数直接给出变量地址)
    Mov AX, [EBX + offset TMyRecord.Age]  // 正确读取Age字段的值,此时AX=99
    // 也可以直接用常量偏移:因为Name是4字节string指针,Age偏移为4
    // Mov AX, [EBX + 4]
  END;
end;

begin
  with recMyRecord do
  begin
    name := 'John Smith';
    age  := 99;
    sex  := 'M'
  end;
  Test(recMyRecord);
  Writeln('Age: ', recMyRecord.Age); // 输出99,验证正确
  Readln;
end.

补充说明

  • 如果需要修改字段值,直接反向操作即可:比如Mov [EBX + offset TMyRecord.Age], AX就能修改Age的值。
  • 用offset TMyRecord.Age比硬编码常量偏移更可靠,后续修改记录结构时编译器会自动更新偏移值,避免手动维护出错。

内容的提问来源于stack exchange,提问作者Bruce Gavin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 22:30:27