2016-07-11 14 views
1

Я работаю в 16-битной сборке NASM, имеющей проблему, когда мой код не будет создан. Ошибка происходит на всех варисторов линий здесь:Ошибка: размер операции не указан - NASm

section .bss 
    x_coord RESB 8 ; [x_coord] is the head, [x_coord+2] is the next cell, etc. 
    y_coord RESB 8 ; Same here 
    pixel_x RESB 2 ; Storage for calculations 
    pixel_y RESB 2 ; Storage for calculations 

    ... 


    MOV [pixel_x], [x_coord] 
    MOV [pixel_y], [y_coord] 
    CALL DrawPixel 

    MOV [pixel_x], [x_coord+2] 
    MOV [pixel_y], [y_coord+2] 
    CALL DrawPixel 

    MOV [pixel_x], [x_coord+4] 
    MOV [pixel_y], [y_coord+4] 
    CALL DrawPixel 

    MOV [pixel_x], [x_coord+6] 
    MOV [pixel_y], [y_coord+6] 
    CALL DrawPixel 

я прочитал, что это происходит потому, что ассемблер не знает, какой размер переменные. Я попробовал MOV [pixel_x], byte [x_coord], предложенный некоторыми сообщениями в сети, но это дает ту же ошибку. Я просто хочу скопировать первые два байта x_coord и y_coord в pixel_x/pixel_y, затем следующие два, затем следующие два, затем следующие два. Как я могу сделать эту работу?

Спасибо :)

ответ

4

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

MOV ax, word [x_coord] 
MOV word [pixel_x], ax 
MOV ax, word [y_coord] 
MOV word [pixel_y], ax 
CALL DrawPixel 

поскольку ваши переменные являются смежными в памяти, вы можете также быть в состоянии сделать это:

MOV eax, dword [x_coord] ; move BOTH x_coord AND y_coord into the register 
MOV dword [pixel_x], eax ; populates BOTH pixel_x AND pixel_y 
CALL DrawPixel 

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

MOV eax, dword [x_coord] 
MOV dword [pixel_x], eax 
CALL DrawPixel 
MOV eax, dword [x_coord+2] 
MOV dword [pixel_x], eax 
CALL DrawPixel 
MOV eax, dword [x_coord+4] 
MOV dword [pixel_x], eax 
CALL DrawPixel 
MOV eax, dword [x_coord+6] 
MOV dword [pixel_x], eax 
CALL DrawPixel 

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

(Помимо: также рассмотреть возможность реализации DrawPixel использовать значения из регистра.)

+0

Это выглядит отлично, спасибо! О вашем последнем комментарии я использовал память, потому что я не уверен на 100%, что регистрирует, что я могу использовать для значений темпа, подобных этому. Что лучше для этого? – Nathan

+2

@Nathan: Это зависит от ABI функции. Если вы написали обе функции, вы можете составить собственное соглашение о вызовах. Посмотрите на некоторые существующие соглашения об ABI/вызовах в вики [x86 tag wiki] (http://stackoverflow.com/tags/x86/info). 32-разрядный __vectorcall от Microsoft, вероятно, является хорошей отправной точкой для 16-битного кода, где первые два целых аргумента передаются в регистры. (edx и ecx, IIRC). 32-битный SysV (Linux) передает аргументы только в стек. Даже это было бы лучшим выбором, чем прохождение args в глобальном масштабе. ('push' работает с операндом памяти). –

+0

@Nathan: Если вы используете nasm в 64-битном режиме, то в этом порядке передаются целочисленные значения: 'rdi',' rsi', 'rdx',' rcx', 'r8',' r9', поэтому вы, скорее всего, напишете свою функцию 'drawPixel', упаковывая две координаты в 32-битные разряды младшего порядка' rdi', а именно 'edi'. Внутри функции следует сохранять 'rbp',' rbx', 'r12',' r13', 'r14' и' r15'. Но существует гораздо больше функций, вызывающих соглашения (включая выравнивание, регистры с плавающей запятой, возвращаемые значения и т. Д.), Поэтому см. Http://www.nasm.us/doc/nasmdo11.html и http://x86-64.org /documentation/abi.pdf. –

 Смежные вопросы

  • Нет связанных вопросов^_^