Обновить

Комментарии 8

Операция mul является самой старой и примитивной: она умножает значение в текущем регистре на значение, которое было в предыдущем регистре. То есть, если вы пишете:

mov eax, 4
mov ecx, 3
mul eax

То команда берет значение eax, умножает его на значение в предыдущей строке ecx и сохраняет туда же, в eax


MUL не так работает.

Нет, все так. Только в команде mul опечатка, не eax (что бессмысленно), а ecx.

это не опечатка, там же формулировка изначально неверная: "она умножает значение в текущем регистре на значение, которое было в предыдущем регистре".

mul всегда умножает сожержимое AL/AX/EAX на любой регистр указанный как операнд. Никаких "предыдущих регистров".

Учитывая фигню написанную и про трехоперандный imul, я почти уверен, что это писала нейросетка. ЧатЖПТ часто так тупит. Алсо, статья озаглавлена как методичка по asm x86-32, но почему-то упоминаются 64-разрядные регистры.

Дальше я просто проверять не стал, уверен, там и в остальном полно нейро-галлюцинаций.

ЗЫ: к слову "mul eax" не бессмысленно, просто на выходе в EAX будет возведенное в квадрат число, в данном случае будет 16. А еще это обнулит EDX.

Пример использования IMUL с тремя операндами:

mov eax, 0xFAFe
mov ebx, 3
imul edx, eax, ebx

Так сделать нельзя. Третий операнд imul может быть только константой.

Вы нейросетку штоле попросили сгенерировать вам методичку?

Да сейчас такая методичка слегка устарела:

vector_loop:
    vmovdqu32 zmm1, zmmword ptr [rsi]
    add       rsi, 64
    kxnorw    k1, k1, k1 
    vgatherdps zmm2 {k1}, [rbx + 4 * zmm1]
    vcmpltps  k1, zmm2, zmm30 {sae}
    vpcompressd [rdi] {k1}, zmm1
    kmovw     edx, k1
    popcnt    edx, edx
    lea       rax, [rax + 4 * rdx - 64]
    lea       rdi, [rdi + 4 * rdx]
    knotw     k1, k1
    vpcompressd [rax] {k1}, zmm1
    sub       rcx, 16
    jnb       vector_loop

Просто для меня наилучшим способом научится и разобраться является «составление учебника» для самого себя.

Ваша статья слегка выиграла бы, если бы продемонстрировала решение какой-нибудь нетривиальной задачи. Заодно и картинки бы показали для разнообразия. Например, в моей статье: «IdaPro v.6.1 demo: Серьезное испытание» ( https://erfaren.narod.ru/Asm/Erfaren005.htm ), я дизассемблировал и перекомпилировал полученный код заново для бинарников: «explorer.exe» и «comctl32.dll» из Windows XP, sp3.

Вот результаты работы перекомпилированных модулей:

Вид перекомпилированного файла explorer.exe
Вид перекомпилированного файла explorer.exe
Результат подмены перекомпилированной comctl32.dll вместо системной библиотеки
Результат подмены перекомпилированной comctl32.dll вместо системной библиотеки

Ну а сам ассемблер осваивался по ходу, на базе реального дизассемблированного листинга.

Вообще, это общий принцип, вместо скучного штудирования учебника, например грамматики французского языка, от русскоязычных авторов, лучше попытаться сделать самому его двуязычный аналог для оригинального учебника на французском языке, от франкоговорящих авторов:

Двуязычный учебник грамматики по французскому языку, горизонтальное представление.
Двуязычный учебник грамматики по французскому языку, горизонтальное представление.
 Двуязычный учебник грамматики по французскому языку, вертикальное представление.
Двуязычный учебник грамматики по французскому языку, вертикальное представление.

Т.е., то, что сами создаете в результате обучения – запоминается лучше, чем при пассивном чтении.

mov ebx, 0x00000005
not ebx ; получили отрицательное число
not ebx ; инвертировали его обратно
inc ebx ; получили число, к которому можем мысленно подставить знак .

Но погодите! Мы получили при таком инвертировании –6, а не –5, как ожидалось! Почему же так?


Потому что существует инструкция NEG, для изменения знака числа.
А NOT просто инвертирует биты.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации