You are on page 1of 10

��visual c++��ʹ����j���

monday, 27. february 2006, 03:35:43

��j���, __asm

http://www.yesky.com/20021014/1634708.shtml

����һ����j������ȱ��

������Ϊ��visual c++��ʹ����j�� ��Ҫ����ı������j�����ҿ��Դ���visual c++�в������


ܴ һЩ���飬

���ҿ���ʹ����c/c++�еı� �����Էdz���� 㡣��j�����Ҫ�������³���:

����1.ʹ�û������д����
����2.���‫�ٶ‬Ҫ��dz�� Ĵ��룻

����3.�豸�������ֱ�ӷ���Ӳ����

����4."naked" call�ij�ʼ��� �����롣

����//(."naked"��������� �����Dz�֪����ô����^_^����ž��Dz���Ҫc/c++�ı�����(�������)��ɵĺ��

��ʼ������β���룬��ο�msdn��"naked functions"��˵��)

������j�����벻������ֲ�������ij�������

‫ ͵��� ͬ�ڲ‬Ļ ������x86 ��Alpha �������У �Ӧ ���� �


����ʹ ����j �

��ʱ�������ʹ��masm����Ϊmasm֧�ָ��ĵĺ�ָ������ָʾ��

����������j��� ���

������visual c++ʹ����j����ı�����__asm� ����֣�� �����}��ʹ�÷���:

����1.��__asm��

__asm
{
mov al, 2
mov dx, 0xd007
out al, dx
}

����2.��ÿ����ָ��֮ǰ��__asm� ���

__asm mov al, 2


__asm mov dx, 0xd007
__asm out al, dx

������Ϊ__asm� ��������ָ��������� ѻ��ָ�����ͬһ��:

����__asm mov al, 2 __asm mov dx, 0xd007 __asm out al, dx
������ ����һ�ַ�����C/c++�ķ���һ�£������к������
ܶ ŵ ����Ƽ�ʹ�ı�һ�ַ�����

����������c/c++�е�"{}"��__asm���"{}"����Ӱ��c/c++�� �����
� ÷Χ�� ͬʱ��__asm�����Ƕ�‫�ף‬Ƕ��Ҳ�
���Ӱ��� �����÷�Χ��

��������__asm����ʹ�û������

����1.��j���ָ�

������j�����ȫ֧�ֵ�Intel 486ָ� ������ʹ��mmxָ���֧�ֵ�ָ�����ʹ��_emitαָ�

��(_emitαָ��˵�������)��

����2.masm���ʽ

������j������ʹ��masm�еı��ʽ������: mov eax, 1��

����3.���ָʾ�� ����

������ __asm��������ʹ��c/c++��������ͺ �� �������masmָʾ�� ��������

‫__��ָ���������ر‬asm���в�����masm�еĶ���ָʾ��:

DB��dw��dd��dq��dt��Df��Ҳ������dup��This�����masm�ṹ� �¼Ҳ������Ч����j��

����Struc��record��width����Mask��

����4.even��Alignָʾ��

����������j�� ֧�ִ����MASMָʾ����֧��Even��Align������Ҫ��ʱ����Щָʾ���‫������������ڻ‬NOp(� ���)ָ

��ʹ��Ŷ��뵽� ��‫ض‬硣�������ʹijЩ������ ָ��ʱ���и� �Ч�ʡ�

����5.masm��ָʾ��

������j�� �Ǻ��

����ʹ��masm��ָʾ��(MACro��rept��irc��irp��Endm)�ͺ�����(<>��!��&��%��.type)��

����6.��˵��

��������ʹ�üĴ���4˵��Σ��� �α�����ʽ��
���� ˵� es:[bx]�

����7.���ͺ � ��С

�������ǿ���ʹ��length4 ��C/c++�е������е� �‫��������ظ‬һ�����飬

����Ϊһ��ʹ��size4 ��C/c++�б� �Ĵ�С��һ��� �Ĵ�С��Length��Type�ij �TYPe��4 ��һ��� �Ĵ

�С�������һ�����飬��ı���һ�������еĵ��� �‫ص‬Ĵ�С��
����8.‫��ע‬

��������ʹ��c/c++��‫����ͣ�ע‬Ƽ���Asm��‫�";"���ͣ�ע‬š�

����9._emitαָ��

����_emitαָ��� ��masm�е�Db����һ��ֻ����
ܶ һ���ֽ‫�����ڣ‬:

__asm
{
jmp _codeofasm

_emit 0x00 ; �������‫���ڴ‬ε����


_emit 0x01

_codeofasm:
; �����Ǵ���
_emit 0x90 ; nopָ��
}

�����ġ���__asm����ʹ��c/c++���� ��

����c/c++������Ի��ʹ�ã�����j������ʹ��c/c++�ı� �ͺ �����
ܶ c/c++�� �

‫__���ء‬asm���п���ʹ������c/c++ ��:

����1.��ţ���(��š��� �ͺ�����

����2.�� ����
� (�ų� ��
� ö��� (enum)��Ա��

����3.�궨��� ����ָʾ��

����4.‫"(���ͣ�ע‬/**/"��"//"��

����5.�������(����Masm�к �������

����6.typedef��ƣ� ��ptr��type���‫��ض‬Ľṹ��Ա��ö�‫� ����� �ٳ‬ò����

������__asm���У�����ʹ��c/c++��ASM�Ļ������(����: 0x100��100h���� �)��

����__asm���в���ʹ����<<һ���C/c++�����c/c++��Masm �ıIJ�������"*"��"[]"���������Ϊ�ǻ��
��� IJ����‫�����ٸ‬:

int array[10];

__asm mov array[6], bx ; store bx at array+6 (not scaled)

array[6] = 0; /* store 0 at array+12 (scaled) */


����* С����: ��j����У������ʹ��type�����ʹ������cһ�¡����磬����}�������һ���:

__asm mov array[6 * type int], 0 ; store 0 at array + 12

array[6] = 0; /* store 0 at array + 12 */

������j����� ���}��ֱ������c/c++�ı� ��__asm���п��������κη�ţ���(�� ��

�������C/C++�е�� �ṹ����ö�

‫���� �ٳ‬Ψһ����ƣ������"."�����֮ǰ��ָ���� ����typedef��ƣ���__asm����ֻ�����ó� ��ơ� ������

����Ψһ�ģ��������"."�����֮ǰ���ϱ� ���typedef��ơ����磬

�����}��ṹ������same_name����Ա�� :

struct first_type
{
char *weasel;
int same_name;
};

struct second_type
{
int wonton;
long same_name;
};

���������������� :

struct first_type hal;


struct second_type oat;

������ô����������same_name�� �ĵ ‫�ʹ�������ط‬ñ� ����Ϊ


� same_name���Ψһ�ġ���� ⣬�����weasel
�� ��ʹ����ij�
����Ψһ����ƣ�����
��� Խ� Ա� 4���� :

__asm
{
mov ebx, offset hal
mov ecx, [ebx]hal.same_name ; ����ʹ�� 'hal'
mov esi, [ebx].weasel ; ����ʡ�� 'hal'
}

����‫�ע‬⣬ʡ��� � ������Ϊ��д����ķ�� ��ɵĻ��ָ��Ļ���һ��ġ�

������� ������Ƶ ‫���ط‬C++��Ա�� �����Dz�����


ܵ C++�ij� ����

�����塢�Ĵ���ʹ��

����һ��4˵����__asm� ʼ��ʱ� Ĵ����ǿ ģ�������}��__asm֮�

��Ĵ����ֵ��(����msdn��˵�ģ�����ʵ��ʹ��ʱ���֣���� �������������˵"һ��"����������)
�������һ�����������__fastcall�����������‫ڼ‬Ĵ����У��⽫��Ĵ���Ĺ����4��� ���

����Ҫ��һ���������__fastcall�����뱣

��ECx�Ĵ���Ϊ� ������ ij� ��������Ϊ__fastcall�ĺ����в�Ҫ��__asm�顣

�������/gr����ѡ��(��ȫ�ֵı��__fastcall)����ÿ���������__cdecl����__stdcall�������� ��

������ô� ��C������

�������ʹ��eax��ebx��ecx��edx��esi��Edi�Ĵ���� ��Ҫ������������ı���ds�� ss��sp��bp� �‫־‬

�Ĵ����Ǿ�Ӧ��Push������Щ�Ĵ���

�����������иı�������std��Cld�ķ����‫������־‬뽫��ָ��� 4��ֵ��

������‫��ת‬

����������C����ʹ��goto��__asm���еı�Ŵ���Ҳ������__asm����‫__��ת‬asm�����������ı�Ŵ���__a

sm���‫ڵ‬ı���Dz���ִ�Сд��(ָ� ʾ���Ҳ�Dz���ִ
 ָ �Сд��)����:

void func()
{
goto c_dest; /* � � */
goto c_dest; /* ���� */

goto a_dest; /* � � */
goto a_dest; /* � � */

__asm
{
jmp c_dest ; � �
jmp c_dest ; msdn��˵� �����������
� vs.netб�� 룬��Ϊ���� �

jmp a_dest ; � �
jmp a_dest ; � �

a_dest: ; __asm ���


}

c_dest: /* c�ı�� */
return;
}

������Ҫʹ�ú�����Ƶ����ţ�����ʹ������ִ�ж��DZ�Ŵ���������ʾ:

; ����: ʹ�ú�������Ϊ���
jne exit
.
.
.
exit:
; �����Ǹ���Asm����
������ ���$����ָ����ǰλ�ã��������ã�����������‫ת‬:

jne $+5 ; ��������ָ��ij�����5���ֽ�


jmp farlabel
;$+5����������
.
.
.
farlabel:

����� ����ú���

������j������C/c++�������� ����� ��������һ�����C/c++��������:

#include

char szformat[] = "%s %s\n";


char szhello[] = "hello";
char szworld[] = " world";
void main()
{
__asm
{
mov eax, offset szworld
push eax
mov eax, offset szhello
push eax
mov eax, offset szformat
push eax
call printf

//��j������C�������� �����
//�ò�ʹ�ı�Ebx�Ĵ������� ����ADD esp, 12
pop ebx
pop ebx
pop ebx
}
}

����‫��ע‬:��������Ǵ�������ѹ ��

������������
ܹ C++�е����Ա�����ǿ��Է���extern "c"����

����������windows api��������Ҫ�Լ�����ջ����Ϊapi�ķ���ָ����ret n����� �����

�����������������:

#include

char szappname[] = "api test";

void main()
{
char szhello[] = "hello, world!";

__asm
{
push mb_ok or mb_iconinformation
push offset szappname ; ȫ�ֱ� ��offset

lea eax, szhello ; �ֲ��� ��lea


push eax
push 0
call dword ptr [messageboxa] ; ‫�����ע‬�ҷ��˺ô����۲ ŷ��ֲ���call messageboxa
}
}

����һ��4˵����visual c++��ʹ����j�����Ϊ������‫ٶ‬ȣ������Щ������þ�������C/c++д��

�����ˡ�һ������

�����������������Vs.net(��vc7)��c����д�ġ�� �һ��̣������д���ŵ������е�.c�ļ��б��룬

�������‫�����ر‬ã����ɱ��� ��

////////////////////////////////////////////////////////////////////////
// ����
#include
///////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////
//ȫ�ֱ�
hwnd g_hwnd;
hinstance g_hinst;

tchar sztemp[1024];

tchar szappname[] = "crc32 sample";


/////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////
//��������
dword getcrc32(const byte *pbdata, int nsize);
int winapi winmain(hinstance hinstance, hinstance hprevinstance, lpstr lpcmdline,
int icmdshow);
lresult callback windowproc(hwnd hwnd, uint umsg, wparam wparam, lparam lparam);
/////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////
//����
int winapi winmain(hinstance hinstance, hinstance hprevinstance, lpstr lpcmdline,
int icmdshow)
{
msg msg;
wndclassex wndclassex;

g_hinst = hinstance;
wndclassex.cbsize = sizeof(wndclassex);
wndclassex.style = cs_vredraw | cs_hredraw;
wndclassex.lpfnwndproc = (wndproc) windowproc;
wndclassex.cbclsextra = 0;
wndclassex.cbwndextra = 0;
wndclassex.hinstance = g_hinst;
wndclassex.hicon = loadicon(null, idi_application);
wndclassex.hcursor = loadcursor(null, idc_arrow);
wndclassex.hbrbackground = (hbrush) (color_window);
wndclassex.lpszmenuname = null;
wndclassex.lpszclassname = szappname;
wndclassex.hiconsm = null;

registerclassex(&wndclassex);

g_hwnd = createwindowex(0, szappname, szappname, ws_overlapped | ws_caption |


ws_sysmenu | ws_thickframe | ws_minimizebox,
cw_usedefault, cw_usedefault, 300, 70,
null, null, g_hinst, null);

showwindow(g_hwnd, icmdshow);
updatewindow(g_hwnd);

while (getmessage(&msg, null, 0, 0))


{
translatemessage(&msg);
dispatchmessage(&msg);
}
return ((int) msg.wparam);
}
///////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////
‫���ڻ‬
//��‫صص‬
LResult callback windowproc(hwnd hwnd, uint umsg, wparam wparam, lparam lparam)
{
switch (umsg)
{
case wm_create:
createwindowex(ws_ex_clientedge, "edit", null, ws_child | ws_visible | ws_border |
es_autohscroll | es_autovscroll | es_nohidesel | ws_overlapped,
7, 12, 220, 22,
hwnd, (hmenu)1000, g_hinst, null);
createwindowex(0, "button", "&ok", ws_child | ws_visible | bs_pushbutton |
ws_overlapped | bs_flat,
244, 12, 40, 20,
hwnd, (hmenu)idok, g_hinst, null);

break;

case wm_command:
switch (loword(wparam))
{
case idok:
getdlgitemtext(g_hwnd, 1000, sztemp + 100, 800);
wsprintf(sztemp, "��ǰ�ı����‫��ַ��ڵ‬crc32У������: 0x%lx", getcrc32(sztemp + 100,
(int)strlen(sztemp + 100)));
messagebox(g_hwnd, sztemp, szappname, mb_ok|mb_iconinformation);
}
break;

case wm_destroy:
postquitmessage(0);
break;

default:
return (defwindowproc(hwnd, umsg, wparam, lparam));
}
return (0);
}
/////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////
//getcrc32: ���ֽ����Crc32У����
//����:
// pbdata: ָ���ֽ�������‫ַ�׵‬

// nsize: �ֽ����
//
//����ֵ:

// �ֽ����Crc32У����
//
//����ʹ�ò���crc32У���룬� ���Dzο���� ����¡� ì��ܵĽ� ��2������crc ��ƪ����д�ġ�
// �ĵľ���������ο�:
http://asp.7i24.com/netcool/laoluo/articles/show_article.asp?article_id=15
//
//����ʹ����j�����crc32У���룬���ʹ����cpu�еļĴ����‫ٶ‬Ⱥͷ����Զ���ʹ��c/c++�������
ܱ
//
dword getcrc32(const byte *pbdata, int nsize)
{
dword dwcrc32table[256];

__asm //��Ƭ��j����dz�ʼ��crc32��
{
mov ecx, 256

_nexttable:
lea eax, [ecx-1]
push ecx
mov ecx, 8

_nextbit:
shr eax, 1
jnc _notcarry
xor eax, 0xedb88320
_notcarry:
dec ecx
jnz _nextbit
pop ecx
mov [dwcrc32table + ecx*4 - 4], eax
dec ecx
jnz _nexttable
}

__asm //��������crc32����
{
mov eax, -1
mov ebx, pbdata
or ebx, ebx
jz _done
mov ecx, nsize
or ecx, ecx
jz _done

_nextbyte:
mov dl, [ebx]

xor dl, al
movzx edx, dl
shr eax, 8
xor eax, [dwcrc32table + edx*4]

inc ebx
loop _nextbyte
_done:
not eax
}
}