неверный суффикс инструкции для mov? - PullRequest
0 голосов
/ 09 мая 2020

У меня есть этот фрагмент встроенного ассемблерного кода, который должен печатать A в текстовом режиме:

    void print(){
        asm volatile(
            "mov ax,0xb800\n"
            "mov ds,ax\n" /*<-as complains about this*/
            "movb 0,'A'\n"
    ); 
} 

Однако, когда я пытаюсь скомпилировать его с помощью g cc (с -m32 и -masm = intel) :

./source/kernel.c: Assembler messages:
./source/kernel.c:4: Error: invalid instruction suffix for `mov'

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

1 Ответ

2 голосов
/ 09 мая 2020

Несмотря на нумерацию строк G CC в сообщении об ошибке, это не та строка, на которую он фактически жалуется, это movb хранилище. Вы можете проверить это, прокомментировав другие инструкции. Ошибка на самом деле выводится ассемблером с нумерацией на основе .loc директив метаданных компилятора, и это многострочный asm-шаблон, поэтому я думаю, это легко go неправильно.

Я подозреваю, что режим GAS .intel_syntax обрабатывает литерал 0 как непосредственный, для согласованности с mov al, 0 с 0 как исходным операндом. Это, конечно, не может работать в качестве пункта назначения.

Сообщение об ошибке «Недопустимый суффикс инструкции» не имеет особого смысла, хотя обратите внимание, что синтаксис Intel не использует суффиксы размера операнда. (Однако по какой-то причине movb [0], 'A' принимается.)

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

    mov  byte ptr [0], 'A'

mov byte ptr ds:0, 'A' также работает, и это синтаксис, который использует objdump -d -Mintel.

Рекомендуется всегда использовать квадратные скобки в операндах памяти, чтобы устранить любую двусмысленность, особенно для людей, которые могут привыкнуть к синтаксису Intel NASM.

...