我目前正在尝试学习 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 //加法是可交换的
我错了,错过了什么吗?