YASM: Инструкция movsx отказывается от двойного слова для размера операнда?

Программа сборки, которую я пишу, не будет компилироваться с ассемблером y, цитируя:

error: invalid size for operand 2

В следующей строке:

movsx rbx, dword [rsi+4*rcx]    ; Copy double-word and sign extend.

Однако я не могу найти причину, по которой dword не должен работать. Я хочу переместить двойное слово (4 байта) по адресу rsi+4*rcx в 8-байтовый регистр rbx. Таким образом, остается 32 бита, которые нужно «дополнить» после копирования в то, что фактически равно ebx. Если я изменю размер на byte, я не получу ошибки. Но это не то, чего я хочу.

Здесь есть вопрос с похожим названием . Однако плакат забыл включить какие-либо операнды размера, и ответ на вопрос не решил мою проблему.

Изменить: я добавил полную программу ниже на случай, если конкретный синтаксис, который я скопировал здесь, не является виновником.

    segment .data

a:
    dd  1
    dd  3
    dd  0
    dd  1
    dd  7
    dd  9
    dd  5
    dd  2
b:
    dd  8
    dd  3
    dd  3
    dd  9
    dd  6
    dd  4
    dd  1
    dd  1

p   dq  0

    segment .text
    global main

main:
    xor rax, rax                    ; Set sum to 0.
    xor rcx, rcx                    ; Set counter to 0.
    lea rsi, [a]                    ; Set source 1.
    lea rdi, [b]                    ; Set source 2.

dot:
    movsx rbx, dword [rsi+4*rcx]    ; Copy in double-word.
    movsx rdx, dword [rdi+4*rcx]    ; Copy in other double-word.        
    imul rbx, rdx                   ; Multiply the two double-words.
    add rax, rbx                    ; Sum product so far.
    inc rcx
    cmp rcx, 8
    jz done
    jmp dot

done:
    mov [p], rax

    xor rax, rax
    ret

person Micrified    schedule 05.01.2019    source источник
comment
Ваша программа использует movzx, а не movsx. Опечатка? Инструкции movzx r64, r/m32 нет, потому что вы просто пишете mov r32, r/m32 и позволяете встроенному нулевому расширению делать свою работу.   -  person Raymond Chen    schedule 05.01.2019
comment
@RaymondChen Да, я исправил это. Я экспериментировал, когда скопировал его. Ошибка все еще сохраняется для условия, указанного в заголовке.   -  person Micrified    schedule 05.01.2019
comment
@RaymondChen Его предложение приводит к тем же ошибкам.   -  person Micrified    schedule 05.01.2019
comment
Я закрыл ваш вопрос как дубликат, поскольку у дубликата есть лучший ответ.   -  person fuz    schedule 01.02.2019
comment
@fuz Вопрос, который вы пометили как дубликат, был тем, который я посетил и упомянул в своем посте. Но ответ не решил мою проблему.   -  person Micrified    schedule 01.02.2019
comment
@Micrified В ответе конкретно говорится: «YASM требует, чтобы вы написали dword, хотя он не принимает там byte, word или qword, а также не принимает movsx rcx, dword [c] (т. е. требует мнемоника movsxd для 32-битных исходных операндов). Это тот же самый совет, который я дал в своем ответе.   -  person fuz    schedule 01.02.2019


Ответы (1)


Ассемблер по какой-то причине вызывает нужную инструкцию movsxd:

movsxd rbx, dword [rsi+4*rcx]

Это должно работать.

person fuz    schedule 05.01.2019
comment
К сожалению, я все еще получаю: invalid size for operand 2 в качестве обратной связи, когда это предложение было реализовано. - person Micrified; 05.01.2019
comment
это странно. Вы тоже пробовали movsxd rbx, [dword rsi+4*rcx] на всякий случай? - person fuz; 05.01.2019
comment
Второе предложение тоже не сработало. Вот краткая демонстрация того, что происходит при компиляции, чтобы было ясно, что я не совершаю ошибки в другом месте. . - person Micrified; 05.01.2019
comment
@Micrified О, ключевое слово dword стоит перед скобками, извините. Можешь попробовать movsxd rbx, dword [rsi+4*rcx], пожалуйста? И я всегда ценю пользователей ACME. - person fuz; 05.01.2019
comment
Теперь программа компилируется и работает корректно. Если вы обновите свой ответ, я с радостью приму его! Я рад, что тебе нравится Акме. Я считаю, что он делает много вещей правильно и хорошо работает с моими небольшими программами. :› - person Micrified; 05.01.2019
comment
по какой-то причине это потому, что AMD назвала его так. Это немного загадка, вместо того, чтобы просто добавить 3-й код операции для movsx, но вы делаете это так, как будто это было странное решение YASM назвать его таким образом. YASM просто опустил псевдоним movsx NASM для movsxd. Забавный факт: код операции для movsxd полезен только с префиксом REX.W. - person Peter Cordes; 05.01.2019
comment
@Micrified: код в вашей ссылке на youtube (!) (расширение целочисленного скалярного произведения с 32 до 64 бит) выглядит как вариант использования SSE2 pmuldq/paddq, поэтому вы можете выполнять пару целых чисел параллельно. Но чтобы накормить его, вам нужно перетасовать свои входы, например. загрузить с помощью SSE4.1 pmovzxdq xmm0, qword [rsi + 4*rcx] или выполнить 128-битную загрузку и punpckldq/hdq для обнуленного регистра. - person Peter Cordes; 05.01.2019
comment
@PeterCordes Я думаю, что эти инструкции на данный момент немного выходят за рамки моих возможностей. Обычно я просто выполняю предложенные упражнения в учебнике, чтобы познакомиться, и у меня есть только поверхностные знания по сборке. Тем не менее, мне всегда интересно узнать о более быстрых способах сделать что-то! Если вы опубликуете это как ответ с немного большим контекстом, я проголосую за него (я уже принял ответ). Тем не менее спасибо за ваш вклад! - person Micrified; 06.01.2019
comment
@Micrified: Как только вы узнаете что-нибудь о SIMD, вы сможете понять, о чем я говорю. См. также agner.org/optimize, в его руководстве по оптимизации есть глава о SIMD. Будем надеяться, что компиляторы также могут автоматически векторизовать способ, который я предложил из цикла C, чтобы вы могли получить пример таким образом. - person Peter Cordes; 06.01.2019