Использование локальных переменных в блоке _asm в C - PullRequest
2 голосов
/ 05 октября 2011

Я пишу программу на 16-битном Turbo C ++ версии 3.0 на основе частичной сборки и кода C. Я должен использовать локальные переменные кода C в блоке сборки. Я отладил следующий код в Borland C ++ 5 и MS VC ++ 6. Он отлично работает, но эти компиляторы 32-битные, поэтому я должен сделать это в Turbo C. В Turbo C ++ он отображает ошибку: «Неверное сочетание кода операции и oprends» код:

void AssignPixel (int X,int Y,int R,int G, int B )
{
_asm {
mov dx, 0x3c8
mov al, 4
out dx, al
inc dx
mov al, R   // ERROR
out dx, al
mov al, G   // ERROR
out dx, al
mov al, B   // ERROR
out dx, al

     mov ah , 0x0c 
     mov al , 4    
     mov cx , X  // ERROR
     mov dx , Y  // ERROR
     int       0x10 
}

Есть ли способ использовать переменные с кодом сборки. Пример кода будет оценен.

Ответы [ 3 ]

4 голосов
/ 05 октября 2011

В сборке Turbo C имена переменных представляют свои адреса. Так что если вы делаете

mov ax, R

вы загружаете адрес R (то есть &R) в топор. Но если вы попробуете:

mov al, R

вы получаете ошибку, потому что адреса имеют ширину 16 бит, а регистр al - только 8 бит.

Если вы напишите:

mov al, [R]

, что эквивалентно:

mov al, byte ptr [R]

затем вы загружаете байт, на который указывает R, в регистр al. (Значение byte ptr автоматически выводится из размера известного операнда, в данном случае al).

Но обратите внимание, что ассемблер ничего не знает о типах ваших переменных, так что вы один на этом. Например, в вашем коде R - это целое число (16 бит), но последняя строка загружает только один байт. Поскольку вы используете машину с прямым порядком байтов, вы получаете наименее значимый байт, который эквивалентен приведению к типу char, вероятно, к тому, что вы хотите.

Конечно, если вам нужно полное значение R, просто напишите:

mov ax, [R]

, что эквивалентно:

mov ax, word ptr [R]
0 голосов
/ 05 октября 2011

Скорее всего, вы не можете сделать это, потому что размеры регистров и переменных не совпадают (8-битный против 16-битный):

mov al, R
mov al, G
mov al, B

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

mov cx, X
mov dx, Y

Попробуйте вместо этого:

mov al, byte ptr [R] ; I don't remember if the brackets are required here
mov cx, [X]
0 голосов
/ 05 октября 2011

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

Имя переменной - это, по сути, макрос для того, где находится переменная, которая в реализации (для целей сборки) является регистром или слотом в памяти.НТН

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...