Массив записей в HLA, ошибка в книге "Искусство собрания"?

В настоящее время я пытаюсь выучить ассемблер HLA и читаю книгу "Искусство сборки". Я застрял в следующем примере:

    тип
     RecType:
       запись
          arrayField: dword[4,5];
              // Другие поля..
          endrecord;

    статический
    aryOfRecs: recType [3,3];

    // Доступ к aryOfRecs [i, j].arrayField [k, l]:

    intmul (5, i, ebx); // Вычисляет индекс в aryOfRecs
    добавить ( j, ebx); // as (i*5 +j)*@size( recType).
    intmul (@size (recType), ebx);

    intmul (3, k, eax); // Вычисляет индекс в aryOfRecs
    добавить ( l, eax); // as (k*3 + j) (*4 обрабатывается позже).

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

Итак, прежде всего. recType - это запись, имеющая arrayField: dword [4,5] plus - некоторые другие неуказанные поля. Затем - у нас есть aryOfRecs, который является массивом [3,3] recType, объявленным в статическом разделе. Это нормально.

В настоящее время код умножает ebx на @size (recType), чтобы вычислить адрес внутреннего массива (arrayField[4,5]), что не имеет никакого смысла, imho.

Итак, вся формула в книге для вычисления адреса работает так:

БАЗОВЫЙ АДРЕС (aryOfRecs) + (k * 3 + l) * 4 + ((i * 5 + j) * @size (recType)

Я думаю, это должно быть:

БАЗОВЫЙ АДРЕС (aryOfRecs) + (k * 3 + l) * @size( recType) + ((i * 5 + j) * 4 вместо?

Так что, либо - Рэндалл Хайд допустил ошибку в этом примере (и да, я проверил ошибки на странице HLA. Об этом ничего не сказано), или у меня со вчерашнего дня был мозговой перебор;>

Последняя строка: mov( aryOfRecs.arrayField[ ebx + eax*4 ], eax);

По сути, он суммирует смещение (aryOfRecs) + смещение (arrayField) + смещение (ebx) + смещение (eax * 4)

arrayField является первым полем в записи recType, поэтому я предположил, что в этом конкретном случае значение смещения arrayField (по отношению к recType) будет равно +0. Это в основном - карты в начале recType. Так что, я думаю, это было включено только в качестве общего правила, чтобы охватить случаи, когда порядок полей в записи recType был бы другим (и arrayField не был бы первым полем в recType). Итак - я пропустил значение OFFSET(arrayField) в двух формулах выше.

И снова - OFFSET(eax*4) идет с "внешним" массивом. Умножать eax на размер меча (4) - не имеет никакого смысла..

Итак, я ожидаю, что код будет делать что-то вроде этого:

    intmul (5, i, ebx); // Вычисляет индекс в  aryOfRecs  arrayField
    добавить ( j, ebx); //  как (i*5 +j)*@size( recType)  как (i*5 +j)*4 или (i*5 +j)*@size(dword)
    // *4 обрабатывается позже, в последней строке с адресацией с масштабированным индексом, 
    // сохранить одну (shl ebx на 2 или intmul ebx на 4) инструкцию
     intmul (@size (recType), ebx); 

    intmul (3, k, eax); // Вычисляет индекс в aryOfRecs
    добавить (l, eax); //  как (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
    // сложение коммутативно

Я ошибаюсь и что-то упустил?

0 ответов

Другие вопросы по тегам