2

我目前正在尝试学习 HLA 汇编程序,并且正在阅读《汇编艺术》一书。我被困在下面的例子中:

    类型
     记录类型:
       记录
          arrayField: dword[4,5];
              // 其他字段
              ..
          结束记录;

    静止的
    aryOfRecs:recType[3,3];

    // 访问 aryOfRecs[i,j].arrayField[k,l]:

    intmul( 5, 我, ebx ); // 计算 aryOfRecs 的索引
    添加(j,ebx);// 如 (i*5 +j)*@size( recType )。
    intmul(@size(recType), ebx);

    intmul(3, k, eax); // 计算 aryOfRecs 的索引
    添加(升,eax);// as (k*3 + j) (*4 稍后处理)。

    mov(aryOfRecs.arrayField[ebx + eax*4], eax);

所以,首先。recType 是一条记录,具有 arrayField: dword [4,5] 加上 - 其他一些未指定的字段。然后 - 我们得到了 aryOfRecs,它是一个在静态部分中声明的 recType 数组 [3,3]。没关系。

目前,代码将 ebx 乘以 @size( recType ) 来计算内部数组的地址 (arrayField[4,5]),这没有任何意义,恕我直言。

所以,书中地址计算的整个公式是这样的:

基址 (aryOfRecs) + (k*3+l) *4 + ((i*5+j)* @size( recType )

我想应该是:

基址 (aryOfRecs) + (k*3+l) *@size( recType ) + ((i*5+j) *4代替?

所以,要么 - Randall Hyde 在这个例子中犯了一个错误(是的,我已经检查了 HLA 页面上的勘误表。它没有说明这一点),或者我从昨天开始就犯了一个错误;>

最后一行是: mov( aryOfRecs.arrayField[ ebx + eax*4 ], eax );

基本上,它总结了 OFFSET(aryOfRecs) + OFFSET(arrayField) + OFFSET(ebx) + OFFSET(eax*4)

arrayField 是 recType 记录中的第一个字段,所以我假设在这种特殊情况下 - arrayField 的偏移值(相对于 recType)将为 +0。它基本上 - 映射在 recType 的开头。所以我猜它只是作为一般规则包含在内,以涵盖recType记录中字段顺序不同的情况(并且arrayField不会是recType中的第一个字段)。所以 - 我在上面的两个公式中跳过了 OFFSET(arrayField) 的值。

再一次 - OFFSET(eax*4) 与“外部”数组一起使用。将 eax 乘以 dword (4) 的大小 - 没有任何意义..

所以,我希望代码能做这样的事情:

    intmul( 5, 我, ebx ); // 计算索引aryOfRecs数组字段
    添加(j,ebx);//如 (i*5 +j)*@size( recType )如 (i*5 +j)*4 或 (i*5 +j)*@size(dword)
    // *4 稍后处理,在最后一行使用缩放索引寻址,
    // 保存一条(shl ebx by 2 或 intmul ebx by 4)指令
    intmul(@size(recType), ebx);

    intmul(3, k, eax); // 计算 aryOfRecs 的索引
    添加(升,eax);//  as (k*3 + j)(*4 稍后处理)如 (k*3 + l)*@size(recType)
    intmul(@size(recType), eax);

    mov(aryOfRecs.arrayField[ebx + eax*4], eax);
    mov(aryOfRecs.arrayField[ebx*4 + eax], eax); //ebx*4 因为@size(dword) = 4
    //加法是可交换的

我错了,错过了什么吗?

4

0 回答 0