Sporą niedogodnością jest fakt, że kompilator Borland C++ (v3.x), mimo opcji generowania kodu 80386, nie rozpoznaje właściwych dla tego procesora rozkazów asemblerowych wpisanych przy pomocy instrukcji "asm". Można używać w ten sposób tylko 16-bitowych rozkazów 286, co znacznie obniża przydatność wbudowanego asemblera.
Przykład:
asm add eax,edx // BŁĄD
386 rozpoznaje rozkazy rozpoczynające się bajtem 66h jako rozszerzone, czyli odnoszące się do podwójnych słów (dword) i 32-bitowych rejestrów. Można więc oszukać kompilator (niezależnie od opcji generowanego kodu). Wystarczy poprzedzić rozkaz 16-bitowy bajtem rozszerzenia:
asm db 0x66 // dla 286 jest to dana asm add ax,dx // uzyskujemy add eax,edx
Dla wygody możemy utworzyć makro, którego będziemy używać dla uzyskania rozkazów rozszerzonych:
#define xasm asm db 0x66; asm
Przykłady:
xasm xor dx,dx // xor edx,edx xasm shl ax,16 // shl eax,16 xasm mov dx,WORD PTR[xLong] // mov edx,DWORD PTR[xLong]
Sprawa trochę się komplikuje, gdy operujemy wartościami natychmiastowymi. Aby np. wpisać liczbę typu long do rejestru 32-bitowego należy użyć dodatkowej danej 16-bitowej (dw) jako starszego słowa naszej wartości natychmiastowej.
Przykład:
xasm mov ax,0x1234 // mov eax,0x77881234h asm dw 7788h
Jest to spowodowane tym, że w rozkazie 16-bitowym kompilator generuje daną natychmiastową 16-bitową. Procesor, odczytując rozkaz jako 32-bitowy, pobiera dodatkowo dwa najstarsze bajty wartości natychmiastowej.
Sposób ten może być szczególnie przydatny, gdy np. optymizujemy we wbudowanym asemblerze Borland C procedurę operującą na zmiennych 32-bitowych (long). Możemy wykorzystać dokładne mnożenie i dzielenie, bardzo wygodne staje się przesuwanie bitowe.
Właściwie należałoby jeszcze sprawdzić, czy procesor to przynajmniej 386...
Stronę opracował Michał Szulowski