ºìÁªLinuxÃÅ»§
Linux°ïÖú

Linux ÖÐ x86 µÄÄÚÁª»ã±à

·¢²¼Ê±¼ä:2006-04-18 13:42:41À´Ô´:ºìÁª×÷Õß:ABC
Bharata B. Rao ÌṩÁËÔÚ Linux ƽ̨ÉÏʹÓú͹¹Ôì x86 ÄÚÁª»ã±àµÄ¸ÅÀ¨ÐÔ½éÉÜ¡£Ëû½éÉÜÁËÄÚÁª»ã±à¼°Æä¸÷ÖÖÓ÷¨µÄ»ù´¡ÖªÊ¶£¬ÌṩÁËһЩ»ù±¾µÄÄÚÁª»ã±à±àÂëÖ¸µ¼£¬²¢½âÊÍÁËÔÚ Linux ÄÚºËÖÐÄÚÁª»ã±à´úÂëµÄһЩʵÀý¡£

Èç¹ûÄúÊÇ Linux Äں˵Ŀª·¢ÈËÔ±£¬Äú»á·¢ÏÖ×Ô¼º¾­³£Òª¶ÔÓëÌåϵ½á¹¹¸ß¶ÈÏà¹ØµÄ¹¦ÄܽøÐбàÂë»òÓÅ»¯´úÂë·¾¶¡£ÄúºÜ¿ÉÄÜÊÇͨ¹ý½«»ã±àÓïÑÔÖ¸Áî²åÈëµ½ C Óï¾äµÄÖм䣨ÓÖ³ÆΪÄÚÁª»ã±àµÄÒ»ÖÖ·½·¨£©À´Ö´ÐÐÕâЩÈÎÎñµÄ¡£ÈÃÎÒÃÇ¿´Ò»Ï Linux ÖÐÄÚÁª»ã±àµÄÌض¨Ó÷¨¡££¨ÎÒÃǽ«ÌÖÂÛÏÞÖÆÔÚ IA32 »ã±à¡££©

GNU »ã±à³ÌÐò¼òÊö

ÈÃÎÒÃÇÊ×ÏÈ¿´Ò»Ï Linux ÖÐʹÓõĻù±¾»ã±à³ÌÐòÓï·¨¡£GCC£¨ÓÃÓÚ Linux µÄ GNU C ±àÒëÆ÷£©Ê¹Óà AT&T »ã±àÓï·¨¡£ÏÂÃæÁгöÁËÕâÖÖÓï·¨µÄһЩ»ù±¾¹æÔò¡££¨¸ÃÁбí¿Ï¶¨²»ÍêÕû£»Ö»°üÀ¨ÁËÓëÄÚÁª»ã±àÏà¹ØµÄÄÇЩ¹æÔò¡££©

¼Ä´æÆ÷ÃüÃû
¼Ä´æÆ÷Ãû³ÆÓÐ % ǰ׺¡£¼´£¬Èç¹û±ØÐëʹÓà eax£¬ËüÓ¦¸ÃÓÃ×÷ %eax¡£

Ô´²Ù×÷ÊýºÍÄ¿µÄ²Ù×÷ÊýµÄ˳Ðò
ÔÚËùÓÐÖ¸ÁîÖУ¬ÏÈÊÇÔ´²Ù×÷Êý£¬È»ºó²ÅÊÇÄ¿µÄ²Ù×÷Êý¡£ÕâÓ뽫Դ²Ù×÷Êý·ÅÔÚÄ¿µÄ²Ù×÷ÊýÖ®ºóµÄ Intel Óï·¨²»Í¬¡£


mov %eax, %ebx, transfers the contents of eax to ebx.


²Ù×÷Êý´óС
¸ù¾Ý²Ù×÷ÊýÊÇ×Ö½Ú (byte)¡¢×Ö (word) »¹Êdz¤ÐÍ (long)£¬Ö¸ÁîµÄºó׺¿ÉÒÔÊÇ b¡¢w »ò l¡£Õâ²¢²»ÊÇÇ¿ÖÆÐԵģ»GCC »á³¢ÊÔͨ¹ý¶ÁÈ¡²Ù×÷ÊýÀ´ÌṩÏàÓ¦µÄºó׺¡£µ«ÊÖ¹¤Ö¸¶¨ºó׺¿ÉÒÔ¸ÄÉÆ´úÂëµÄ¿É¶ÁÐÔ£¬²¢¿ÉÒÔÏû³ý±àÒëÆ÷²Â²â²»ÕýÈ·µÄ¿ÉÄÜÐÔ¡£


movb %al, %bl -- Byte move
movw %ax, %bx -- Word move
movl %eax, %ebx -- Longword move


Á¢¼´²Ù×÷Êý
ͨ¹ýʹÓà $ Ö¸¶¨Ö±½Ó²Ù×÷Êý¡£


movl $0xffff, %eax -- will move the value of 0xffff into eax register.


¼ä½ÓÄÚ´æÒýÓÃ
ÈκζÔÄÚ´æµÄ¼ä½ÓÒýÓö¼ÊÇͨ¹ýʹÓà ( ) À´Íê³ÉµÄ¡£

movb (%esi), %al -- will transfer the byte in the memory


pointed by esi into al
register


ÄÚÁª»ã±à

GCC ΪÄÚÁª»ã±àÌṩÌØÊâ½á¹¹£¬Ëü¾ßÓÐÒÔϸñʽ£º

GCG µÄ "asm" ½á¹¹

asm ( assembler template


: output operands (optional)


: input operands (optional)


: list of clobbered registers
(optional)


);


±¾ÀýÖУ¬»ã±à³ÌÐòÄ£°åÓÉ»ã±àÖ¸Áî×é³É¡£ÊäÈë²Ù×÷ÊýÊdz䵱ָÁîÊäÈë²Ù×÷ÊýʹÓÃµÄ C ±í´ïʽ¡£Êä³ö²Ù×÷ÊýÊǽ«¶ÔÆäÖ´Ðлã±àÖ¸ÁîÊä³öµÄ C ±í´ïʽ¡£

ÄÚÁª»ã±àµÄÖØÒªÐÔÌåÏÖÔÚËüÄܹ»Áé»î²Ù×÷£¬¶øÇÒ¿ÉÒÔʹÆäÊä³öͨ¹ý C ±äÁ¿ÏÔʾ³öÀ´¡£ÒòΪËü¾ßÓÐÕâÖÖÄÜÁ¦£¬ËùÒÔ "asm" ¿ÉÒÔÓÃ×÷»ã±àÖ¸ÁîºÍ°üº¬ËüµÄ C ³ÌÐòÖ®¼äµÄ½Ó¿Ú¡£

Ò»¸ö·Ç³£»ù±¾µ«ºÜÖØÒªµÄÇø±ðÔÚÓÚ ¼òµ¥ÄÚÁª»ã±àÖ»°üÀ¨Ö¸Á¶ø À©Õ¹ÄÚÁª»ã±à°üÀ¨²Ù×÷Êý¡£ÒªËµÃ÷ÕâÒ»µã£¬¿¼ÂÇÒÔÏÂʾÀý£º

ÄÚÁª»ã±àµÄ»ù±¾ÒªËØ

{
int a=10, b;
asm ("movl %1, %%eax;



movl %%eax, %0;"
:"=r"(b) /* output */
:"r"(a) /* input */
:"%eax"); /* clobbered register */
}


ÔÚÉÏÀýÖУ¬ÎÒÃÇʹÓûã±àÖ¸Áîʹ "b" µÄÖµµÈÓÚ "a"¡£Çë×¢ÒâÒÔϼ¸µã£º

* "b" ÊÇÊä³ö²Ù×÷Êý£¬ÓÉ %0 ÒýÓã¬"a" ÊÇÊäÈë²Ù×÷Êý£¬ÓÉ %1 ÒýÓá£
* "r" ÊDzÙ×÷ÊýµÄÔ¼Êø£¬ËüÖ¸¶¨½«±äÁ¿ "a" ºÍ "b" ´æ´¢ÔڼĴæÆ÷ÖС£Çë×¢Ò⣬Êä³ö²Ù×÷ÊýÔ¼ÊøÓ¦¸Ã´øÓÐÒ»¸öÔ¼ÊøÐÞÊηû "="£¬Ö¸¶¨ËüÊÇÊä³ö²Ù×÷Êý¡£
* ÒªÔÚ "asm" ÄÚʹÓüĴæÆ÷ %eax£¬%eax µÄÇ°ÃæÓ¦¸ÃÔÙ¼ÓÒ»¸ö %£¬»»¾ä»°Ëµ¾ÍÊÇ %%eax£¬ÒòΪ "asm" ʹÓà %0¡¢%1 µÈÀ´±êʶ±äÁ¿¡£ÈκδøÓÐÒ»¸ö % µÄÊý¶¼¿´×÷ÊÇÊäÈ룯Êä³ö²Ù×÷Êý£¬¶ø²»ÈÏΪÊǼĴæÆ÷¡£
* µÚÈý¸öðºÅºóµÄÐÞÊμĴæÆ÷ %eax ¸æËß½«ÔÚ "asm" ÖÐÐÞ¸Ä GCC %eax µÄÖµ£¬ÕâÑù GCC ¾Í²»Ê¹ÓøüĴæÆ÷´æ´¢ÈκÎÆäËüµÄÖµ¡£
* movl %1, %%eax ½« "a" µÄÖµÒƵ½ %eax ÖУ¬ movl %%eax, %0 ½« %eax µÄÄÚÈÝÒƵ½ "b" ÖС£
* ÒòΪ "b" ±»Ö¸¶¨³ÉÊä³ö²Ù×÷Êý£¬Òò´Ëµ± "asm" µÄÖ´ÐÐÍê³Éºó£¬Ëü½«·´Ó³³ö¸üеÄÖµ¡£»»¾ä»°Ëµ£¬¶Ô "asm" ÄÚ "b" Ëù×öµÄ¸ü¸Ä½«ÔÚ "asm" Íâ·´Ó³³öÀ´¡£

ÏÖÔÚÈÃÎÒÃǸüÏêϸµÄÁ˽âÿһÏîµÄº¬Òå¡£



»ã±à³ÌÐòÄ£°å

»ã±à³ÌÐòÄ£°åÊÇÒ»×é²åÈëµ½ C ³ÌÐòÖеĻã±àÖ¸Á¿ÉÒÔÊǵ¥¸öÖ¸ÁҲ¿ÉÒÔÊÇÒ»×éÖ¸Á¡£Ã¿ÌõÖ¸ÁӦ¸ÃÓÉË«ÒýºÅÀ¨Æ𣬻òÕßÕû×éÖ¸ÁîÓ¦¸ÃÓÉË«ÒýºÅÀ¨Æð¡£Ã¿ÌõÖ¸ÁӦ¸ÃÓÃÒ»¸ö¶¨½ç·û½áβ¡£ÓÐЧµÄ¶¨½ç·ûΪÐÂÐÐ (\n) ºÍ·ÖºÅ (;)¡£ '\n' ºó¿ÉÒÔ¸úÒ»¸ö tab(\t) ×÷Ϊ¸ñʽ»¯·ûºÅ£¬Ôö¼Ó GCC ÔÚ»ã±àÎļþÖÐÉú³ÉµÄÖ¸ÁîµÄ¿É¶ÁÐÔ¡£ Ö¸Áîͨ¹ýÊý %0¡¢%1 µÈÀ´ÒýÓà C ±í´ïʽ£¨Ö¸¶¨Îª²Ù×÷Êý£©¡£

Èç¹ûÏ£ÍûÈ·±£±àÒëÆ÷²»»áÔÚ "asm" ÄÚ²¿ÓÅ»¯Ö¸Á¿ÉÒÔÔÚ "asm" ºóʹÓùؼü×Ö "volatile"¡£Èç¹û³ÌÐò±ØÐëÓë ANSI C ¼æÈÝ£¬ÔòÓ¦¸ÃʹÓà __asm__ ºÍ __volatile__£¬¶ø²»ÊÇ asm ºÍ volatile¡£


²Ù×÷Êý

C ±í´ïʽÓÃ×÷ "asm" ÄڵĻã±àÖ¸Áî²Ù×÷Êý¡£ÔÚ»ã±àÖ¸Áîͨ¹ý¶Ô C ³ÌÐòµÄ C ±í´ïʽ½øÐвÙ×÷À´Ö´ÐÐÓÐÒâÒåµÄ×÷ÒµµÄÇé¿öÏ£¬²Ù×÷ÊýÊÇÄÚÁª»ã±àµÄÖ÷ÒªÌØÐÔ¡£

ÿ¸ö²Ù×÷Êý¶¼ÓɲÙ×÷ÊýÔ¼Êø×Ö·û´®Ö¸¶¨£¬ºóÃæ¸úÓÃÀ¨»¡À¨ÆðµÄ C ±í´ïʽ£¬ÀýÈ磺"constraint" (C expression)¡£²Ù×÷ÊýÔ¼ÊøµÄÖ÷Òª¹¦ÄÜÊÇÈ·¶¨²Ù×÷ÊýµÄÑ°Ö··½Ê½¡£

¿ÉÒÔÔÚÊäÈëºÍÊä³ö²¿·ÖÖÐͬʱʹÓöà¸ö²Ù×÷Êý¡£Ã¿¸ö²Ù×÷ÊýÓɶººÅ·Ö¸ô¿ª¡£

ÔÚ»ã±à³ÌÐòÄ£°åÄÚ²¿£¬²Ù×÷ÊýÓÉÊý×ÖÒýÓá£Èç¹û×ܹ²ÓÐ n ¸ö²Ù×÷Êý£¨°üÀ¨ÊäÈëºÍÊä³ö£©£¬ÄÇôµÚÒ»¸öÊä³ö²Ù×÷ÊýµÄ±àºÅΪ 0£¬ÖðÏîµÝÔö£¬×îºóÄǸöÊäÈë²Ù×÷ÊýµÄ±àºÅΪ n -1¡£×ܲÙ×÷ÊýµÄÊýÄ¿ÏÞÖÆÔÚ 10£¬Èç¹û»úÆ÷ÃèÊöÖÐÈκÎÖ¸ÁîģʽÖеÄ×î´ó²Ù×÷ÊýÊýÄ¿´óÓÚ 10£¬ÔòʹÓúóÕß×÷ΪÏÞÖÆ¡£


ÐÞÊμĴæÆ÷Áбí

Èç¹û "asm" ÖеÄÖ¸ÁîÖ¸µÄÊÇÓ²¼þ¼Ä´æÆ÷£¬¿ÉÒÔ¸æËß GCC ÎÒÃǽ«×Ô¼ºÊ¹ÓúÍÐÞ¸ÄËüÃÇ¡£ÕâÑù£¬GCC ¾Í²»»á¼ÙÉèËü×°Èëµ½ÕâЩ¼Ä´æÆ÷ÖеÄÖµÊÇÓÐЧֵ¡£Í¨³£²»ÐèÒª½«ÊäÈëºÍÊä³ö¼Ä´æÆ÷ÁÐΪ clobbered£¬ÒòΪ GCC ÖªµÀ "asm" ʹÓÃËüÃÇ£¨ÒòΪËüÃDZ»Ã÷È·Ö¸¶¨ÎªÔ¼Êø£©¡£²»¹ý£¬Èç¹ûÖ¸ÁîʹÓÃÈκÎÆäËüµÄ¼Ä´æÆ÷£¬ÎÞÂÛÊÇÃ÷È·µÄ»¹ÊÇÒþº¬µÄ£¨¼Ä´æÆ÷²»ÔÚÊäÈëÔ¼ÊøÁбíÖгöÏÖ£¬Ò²²»ÔÚÊä³öÔ¼ÊøÁбíÖгöÏÖ£©£¬¼Ä´æÆ÷¶¼±ØÐë±»Ö¸¶¨ÎªÐÞÊÎÁÐ±í¡£ÐÞÊμĴæÆ÷ÁÐÔÚµÚÈý¸öðºÅÖ®ºó£¬ÆäÃû³Æ±»Ö¸¶¨Îª×Ö·û´®¡£

ÖÁÓڹؼü×Ö£¬Èç¹ûÖ¸ÁîÒÔijЩ²»¿ÉÔ¤ÖªÇÒ²»Ã÷È·µÄ·½Ê½ÐÞ¸ÄÁËÄڴ棬Ôò¿ÉÄܽ« "memory" ¹Ø¼ü×ÖÌí¼Óµ½ÐÞÊμĴæÆ÷ÁбíÖС£ÕâÑù¾Í¸æËß GCC ²»ÒªÔÚ²»Í¬Ö¸ÁîÖ®¼ä½«ÄÚ´æÖµ¸ßËÙ»º´æÔڼĴæÆ÷ÖС£


²Ù×÷ÊýÔ¼Êø

Ç°ÃæÌáµ½¹ý£¬"asm" ÖеÄÿ¸ö²Ù×÷Êý¶¼Ó¦¸ÃÓɲÙ×÷ÊýÔ¼Êø×Ö·û´®ÃèÊö£¬ºóÃæ¸úÓÃÀ¨»¡À¨ÆðµÄ C ±í´ïʽ¡£²Ù×÷ÊýÔ¼ÊøÖ÷ÒªÊÇÈ·¶¨Ö¸ÁîÖвÙ×÷ÊýµÄÑ°Ö··½Ê½¡£Ô¼ÊøÒ²¿ÉÒÔÖ¸¶¨£º

* ÊÇ·ñÔÊÐí²Ù×÷ÊýλÓڼĴæÆ÷ÖУ¬ÒÔ¼°Ëü¿ÉÒÔ°üÀ¨ÔÚÄÄЩÖÖÀàµÄ¼Ä´æÆ÷ÖÐ
* ²Ù×÷ÊýÊÇ·ñ¿ÉÒÔÊÇÄÚ´æÒýÓã¬ÒÔ¼°ÔÚÕâÖÖÇé¿öÏÂʹÓÃÄÄЩÖÖÀàµÄµØÖ·
* ²Ù×÷ÊýÊÇ·ñ¿ÉÒÔÊÇÁ¢¼´Êý

Ô¼Êø»¹ÒªÇóÁ½¸ö²Ù×÷ÊýÆ¥Åä¡£


³£ÓÃÔ¼Êø

ÔÚ¿ÉÓõIJÙ×÷ÊýÔ¼ÊøÖУ¬Ö»ÓÐһС²¿·ÖÊdz£Óõģ»ÏÂÃæÁгöÁËÕâЩԼÊøÒÔ¼°¼òÒªÃèÊö¡£ÓйزÙ×÷ÊýÔ¼ÊøµÄÍêÕûÁÐ±í£¬Çë²Î¿¼ GCC ºÍ GAS Êֲᡣ

¼Ä´æÆ÷²Ù×÷ÊýÔ¼Êø (r)
ʹÓÃÕâÖÖÔ¼ÊøÖ¸¶¨²Ù×÷Êýʱ£¬ËüÃÇ´æ´¢ÔÚͨÓüĴæÆ÷ÖС£Çë¿´ÏÂÀý£º



asm ("movl %%cr3, %0\n" :"=r"(cr3val));


ÕâÀ±äÁ¿ cr3val ±£´æÔڼĴæÆ÷ÖУ¬%cr3 µÄÖµ¸´ÖƵ½¼Ä´æÆ÷ÉÏ£¬cr3val µÄÖµ´Ó¸Ã¼Ä´æÆ÷¸üе½ÄÚ´æÖС£Ö¸¶¨ "r" Ô¼Êøʱ£¬GCC ¿ÉÒÔ½«±äÁ¿ cr3val ±£´æÔÚÈκοÉÓÃµÄ GPR ÖС£ÒªÖ¸¶¨¼Ä´æÆ÷£¬±ØÐëͨ¹ýʹÓÃÌض¨µÄ¼Ä´æÆ÷Ô¼ÊøÖ±½ÓÖ¸¶¨¼Ä´æÆ÷Ãû¡£



a %eax

b %ebx

c %ecx

d %edx

S %esi

D %edi


ÄÚ´æ²Ù×÷ÊýÔ¼Êø (m)
µ±²Ù×÷ÊýλÓÚÄÚ´æÖÐʱ£¬ÈκζÔËüÃÇÖ´ÐеIJÙ×÷¶¼½«ÔÚÄÚ´æλÖÃÖÐÖ±½Ó·¢Éú£¬ÕâÓë¼Ä´æÆ÷Ô¼ÊøÕýºÃÏà·´£¬ºóÕßÏȽ«Öµ´æ´¢ÔÚÒªÐ޸ĵļĴæÆ÷ÖУ¬È»ºó½«Ëüд»ØÄÚ´æλÖÃÖС£µ«¼Ä´æÆ÷Ô¼Êøͨ³£Ö»ÔÚ¶ÔÓÚÖ¸ÁîÀ´ËµËüÃÇÊǾø¶Ô±ØÐèµÄ£¬»òÕßËüÃÇ¿ÉÒÔ´ó´óÌá¸ß½ø³ÌËÙ¶ÈʱʹÓᣵ±ÐèÒªÔÚ "asm" ÄÚ²¿¸üРC ±äÁ¿£¬¶øÄúÓÖȷʵ²»Ï£ÍûʹÓüĴæÆ÷À´±£´æÆäֵʱ£¬Ê¹ÓÃÄÚ´æÔ¼Êø×îΪÓÐЧ¡£ÀýÈ磬idtr µÄÖµ´æ´¢ÔÚÄÚ´æλÖà loc ÖУº



("sidt %0\n" : :"m"(loc));



Æ¥Å䣨Êý×Ö£©Ô¼Êø
ÔÚijЩÇé¿öÏ£¬Ò»¸ö±äÁ¿¼ÈÒª³äµ±ÊäÈë²Ù×÷Êý£¬Ò²Òª³äµ±Êä³ö²Ù×÷Êý¡£¿ÉÒÔͨ¹ýʹÓÃÆ¥ÅäÔ¼ÊøÔÚ "asm" ÖÐÖ¸¶¨ÕâÖÖÇé¿ö¡£



asm ("incl %0" :"=a"(var):"0"(var));


ÔÚÆ¥ÅäÔ¼ÊøµÄʾÀýÖУ¬¼Ä´æÆ÷ %eax ¼ÈÓÃ×÷ÊäÈë±äÁ¿£¬Ò²ÓÃ×÷Êä³ö±äÁ¿¡£½« var ÊäÈë¶ÁÈ¡µ½ %eax£¬Ôö¼Óºó½«¸üÐ嵀 %eax Ôٴδ洢ÔÚ var ÖС£ÕâÀïµÄ "0" Ö¸¶¨µÚ 0 ¸öÊä³ö±äÁ¿ÏàͬµÄÔ¼Êø¡£¼´£¬ËüÖ¸¶¨ var µÄÊä³öʵÀýÖ»Ó¦¸Ã´æ´¢ÔÚ %eax ÖС£¸ÃÔ¼Êø¿ÉÒÔÓÃÓÚÒÔÏÂÇé¿ö£º

* ÊäÈë´Ó±äÁ¿ÖжÁÈ¡£¬»òÕß±äÁ¿±»Ð޸ĺó£¬ÐÞ¸Äд»Øµ½Í¬Ò»±äÁ¿ÖÐ
* ²»ÐèÒª½«ÊäÈë²Ù×÷ÊýºÍÊä³ö²Ù×÷ÊýµÄʵÀý·Ö¿ª

ʹÓÃÆ¥ÅäÔ¼Êø×îÖØÒªµÄÒâÒåÔÚÓÚËüÃÇ¿ÉÒÔµ¼ÖÂÓÐЧµØʹÓÿÉÓüĴæÆ÷¡£



Ò»°ãÄÚÁª»ã±àÓ÷¨Ê¾Àý

ÒÔÏÂʾÀýͨ¹ý¸÷ÖÖ²»Í¬µÄ²Ù×÷ÊýÔ¼Êø˵Ã÷ÁËÓ÷¨¡£ÓÐÈç´Ë¶àµÄÔ¼ÊøÒÔÖÁÓÚÎÞ·¨½«ËüÃÇÒ»Ò»Áгö£¬ÕâÀïÖ»ÁгöÁË×î¾­³£Ê¹ÓõÄÄÇЩԼÊøÀàÐÍ¡£

"asm" ºÍ¼Ä´æÆ÷Ô¼Êø "r" ÈÃÎÒÃÇÏÈ¿´Ò»ÏÂʹÓüĴæÆ÷Ô¼Êø r µÄ "asm"¡£ÎÒÃǵÄʾÀýÏÔʾÁË GCC ÈçºÎ·ÖÅä¼Ä´æÆ÷£¬ÒÔ¼°ËüÈçºÎ¸üÐÂÊä³ö±äÁ¿µÄÖµ¡£

int main(void)
{
int x = 10, y;

asm ("movl %1, %%eax;


"movl %%eax, %0;"
:"=r"(y) /* y is output operand */
:"r"(x) /* x is input operand */
:"%eax"); /* %eax is clobbered register */
}


ÔÚ¸ÃÀýÖУ¬x µÄÖµ¸´ÖÆΪ "asm" ÖÐµÄ y¡£x ºÍ y ¶¼Í¨¹ý´æ´¢ÔڼĴæÆ÷Öд«µÝ¸ø "asm"¡£Îª¸ÃÀýÉú³ÉµÄ»ã±à´úÂëÈçÏ£º

main:

pushl %ebp

movl %esp,%ebp

subl $8,%esp

movl $10,-4(%ebp)

movl -4(%ebp),%edx /* x=10 is stored in %edx */
#APP /* asm starts here */

movl %edx, %eax /* x is moved to %eax */

movl %eax, %edx /* y is allocated in edx and updated */

#NO_APP /* asm ends here */

movl %edx,-8(%ebp) /* value of y in stack is updated with

the value in %edx */

µ±Ê¹Óà "r" Ô¼Êøʱ£¬GCC ÔÚÕâÀï¿ÉÒÔ×ÔÓÉ·ÖÅäÈκμĴæÆ÷¡£ÔÚÎÒÃǵÄʾÀýÖУ¬ËüÑ¡Ôñ %edx À´´æ´¢ x¡£ÔÚ¶ÁÈ¡ÁË %edx ÖÐ x µÄÖµºó£¬ËüΪ y Ò²·ÖÅäÁËÏàͬµÄ¼Ä´æÆ÷¡£

ÒòΪ y ÊÇÔÚÊä³ö²Ù×÷Êý²¿·ÖÖÐÖ¸¶¨µÄ£¬ËùÒÔ %edx ÖиüеÄÖµ´æ´¢ÔÚ -8(%ebp)£¬¶ÑÕ»ÉÏ y µÄλÖÃÖС£Èç¹û y ÊÇÔÚÊäÈ벿·ÖÖÐÖ¸¶¨µÄ£¬ÄÇô¼´Ê¹ËüÔÚ y µÄÁÙʱ¼Ä´æÆ÷´æ´¢Öµ (%edx) Öб»¸üУ¬¶ÑÕ»ÉÏ y µÄÖµÒ²²»»á¸üС£

ÒòΪ %eax ÊÇÔÚÐÞÊÎÁбíÖÐÖ¸¶¨µÄ£¬GCC ²»ÔÚÈκÎÆäËüµØ·½Ê¹ÓÃËüÀ´´æ´¢Êý¾Ý¡£

ÊäÈë x ºÍÊä³ö y ¶¼·ÖÅäÔÚͬһ¸ö %edx ¼Ä´æÆ÷ÖУ¬¼ÙÉèÊäÈëÔÚÊä³ö²úÉú֮ǰ±»ÏûºÄ¡£Çë×¢Ò⣬Èç¹ûÄúÓÐÐí¶àÖ¸Á¾Í²»ÊÇÕâÖÖÇé¿öÁË¡£ÒªÈ·±£ÊäÈëºÍÊä³ö·ÖÅäµ½²»Í¬µÄ¼Ä´æÆ÷ÖУ¬¿ÉÒÔÖ¸¶¨ & Ô¼ÊøÐÞÊηû¡£ÏÂÃæÊÇÌí¼ÓÁËÔ¼ÊøÐÞÊηûµÄʾÀý¡£


int main(void)
{
int x = 10, y;

asm ("movl %1, %%eax;


"movl %%eax, %0;"
:"=&r"(y) /* y is output operand, note the

& constraint modifier. */
:"r"(x) /* x is input operand */
:"%eax"); /* %eax is clobbered register */
}


ÒÔÏÂÊÇΪ¸ÃʾÀýÉú³ÉµÄ»ã±à´úÂ룬´ÓÖпÉÒÔÃ÷ÏԵؿ´³ö x ºÍ y ´æ´¢ÔÚ "asm" Öв»Í¬µÄ¼Ä´æÆ÷ÖС£

main:

pushl %ebp

movl %esp,%ebp

subl $8,%esp

movl $10,-4(%ebp)

movl -4(%ebp),%ecx /* x, the input is in %ecx */
#APP
movl %ecx, %eax
movl %eax, %edx /* y, the output is in %edx */

#NO_APP

movl %edx,-8(%ebp)



Ìض¨¼Ä´æÆ÷Ô¼ÊøµÄʹÓÃ

ÏÖÔÚÈÃÎÒÃÇ¿´Ò»ÏÂÈçºÎ½«¸ö±ð¼Ä´æÆ÷×÷Ϊ²Ù×÷ÊýµÄÔ¼ÊøÖ¸¶¨¡£ÔÚÏÂÃæµÄʾÀýÖУ¬cpuid Ö¸Áî²ÉÓà %eax ¼Ä´æÆ÷ÖеÄÊäÈ룬ȻºóÔÚËĸö¼Ä´æÆ÷Öиø³öÊä³ö£º%eax¡¢%ebx¡¢%ecx¡¢%edx¡£¶Ô cpuid µÄÊäÈ루±äÁ¿ "op"£©´«µÝµ½ "asm" µÄ eax ¼Ä´æÆ÷ÖУ¬ÒòΪ cpuid Ï£ÍûËüÕâÑù×ö¡£ÔÚÊä³öÖÐʹÓà a¡¢b¡¢c ºÍ d Ô¼Êø£¬·Ö±ðÊÕ¼¯Ëĸö¼Ä´æÆ÷ÖеÄÖµ¡£

asm ("cpuid"


: "=a" (_eax),


"=b" (_ebx),


"=c" (_ecx),


"=d" (_edx)


: "a" (op));


ÔÚÏÂÃæ¿ÉÒÔ¿´µ½ÎªËüÉú³ÉµÄ»ã±à´úÂ루¼ÙÉè _eax¡¢_ebx µÈ... ±äÁ¿¶¼´æ´¢ÔÚ¶ÑÕ»ÉÏ£©£º


movl -20(%ebp),%eax /* store 'op' in %eax -- input */
#APP


cpuid
#NO_APP


movl %eax,-4(%ebp) /* store %eax in _eax -- output */


movl %ebx,-8(%ebp) /* store other registers in

movl %ecx,-12(%ebp)
respective output variables */

movl %edx,-16(%ebp)

strcpy º¯Êý¿ÉÒÔͨ¹ýÒÔÏ·½Ê½Ê¹Óà "S" ºÍ "D" Ô¼ÊøÀ´ÊµÏÖ£º


asm ("cld\n

rep\n


movsb"


: /* no input */


:"S"(src), "D"(dst), "c"(count));

ͨ¹ýʹÓà "S" Ô¼Êø½«Ô´Ö¸Õë src ·ÅÈë %esi ÖУ¬Ê¹Óà "D" Ô¼Êø½«Ä¿µÄÖ¸Õë dst ·ÅÈë %edi ÖС£ÒòΪ rep ǰ׺ÐèÒª count Öµ£¬ËùÒÔ½«Ëü·ÅÈë %ecx ÖС£

ÔÚÏÂÃæ¿ÉÒÔ¿´µ½ÁíÒ»¸öÔ¼Êø£¬ËüʹÓÃÁ½¸ö¼Ä´æÆ÷ %eax ºÍ %edx ½«Á½¸ö 32 λµÄÖµºÏ²¢ÔÚÒ»Æð£¬È»ºóÉú³ÉÒ»¸ö64 λµÄÖµ£º

#define rdtscll(val) \


__asm__ __volatile__ ("rdtsc" : "=A" (val))

The generated assembly looks like this (if val has a 64 bit memory space).

#APP

rdtsc
#NO_APP


movl %eax,-8(%ebp) /* As a result of A constraint


movl %edx,-4(%ebp)
%eax and %edx serve as outputs */

Note here that the values in %edx:%eax serve as 64 bit output.



ʹÓÃÆ¥ÅäÔ¼Êø

ÔÚÏÂÃ潫¿´µ½ÏµÍ³µ÷ÓõĴúÂ룬ËüÓÐËĸö²ÎÊý£º


#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
{ \
long __res; \
__asm__ volatile ("int $0x80" \


: "=a" (__res) \

: "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)), \


"d" ((long)(arg3)),"S" ((long)(arg4))); \
__syscall_return(type,__res); \
}


ÔÚÉÏÀýÖУ¬Í¨¹ýʹÓà b¡¢c¡¢d ºÍ S Ô¼Êø½«ÏµÍ³µ÷ÓõÄËĸö×Ô±äÁ¿·ÅÈë %ebx¡¢%ecx¡¢%edx ºÍ %esi ÖС£Çë×¢Ò⣬ÔÚÊä³öÖÐʹÓÃÁË "=a" Ô¼Êø£¬ÕâÑù£¬Î»ÓÚ %eax ÖеÄϵͳµ÷Óõķµ»ØÖµ¾Í±»·ÅÈë±äÁ¿ __res ÖС£Í¨¹ý½«Æ¥ÅäÔ¼Êø "0" ÓÃ×÷ÊäÈ벿·ÖÖеÚÒ»¸ö²Ù×÷ÊýÔ¼Êø£¬syscall ºÅ __NR_##name ±»·ÅÈë %eax ÖУ¬²¢ÓÃ×÷¶Ôϵͳµ÷ÓõÄÊäÈë¡£ÕâÑù£¬ÕâÀïµÄ %eax ¼È¿ÉÒÔÓÃ×÷ÊäÈë¼Ä´æÆ÷£¬ÓÖ¿ÉÒÔÓÃ×÷Êä³ö¼Ä´æÆ÷¡£Ã»ÓÐÆäËü¼Ä´æÆ÷ÓÃÓÚÕâ¸öÄ¿µÄ¡£ÁíÇë×¢Ò⣬ÊäÈ루syscall ºÅ£©ÔÚ²úÉúÊä³ö£¨syscall µÄ·µ»ØÖµ£©Ö®Ç°±»ÏûºÄ£¨Ê¹Óã©¡£


ÄÚ´æ²Ù×÷ÊýÔ¼ÊøµÄʹÓÃ

Ç뿼ÂÇÏÂÃæµÄÔ­×ӵݼõ²Ù×÷£º

__asm__ __volatile__(


"lock; decl %0"


:"=m" (counter)

:"m" (counter));


ΪËüÉú³ÉµÄ»ã±àÀàËÆÓÚ£º


#APP
lock
decl -24(%ebp) /* counter is modified on its memory location */
#NO_APP.

Äú¿ÉÄÜ¿¼ÂÇÔÚÕâÀïΪ counter ʹÓüĴæÆ÷Ô¼Êø¡£Èç¹ûÕâÑù×ö£¬counter µÄÖµ±ØÐëÏȸ´ÖƵ½¼Ä´æÆ÷£¬µÝ¼õ£¬È»ºó¶ÔÆäÄÚ´æ¸üС£µ«ÕâÑùÄú»áÎÞ·¨Àí½âËø¶¨ºÍÔ­×ÓÐÔµÄÈ«²¿Òâͼ£¬ÕâЩÃ÷È·ÏÔʾÁËʹÓÃÄÚ´æÔ¼ÊøµÄ±ØÒªÐÔ¡£


ʹÓÃÐÞÊμĴæÆ÷

Ç뿼ÂÇÄڴ濽±´µÄ»ù±¾ÊµÏÖ¡£

asm ("movl $count, %%ecx;

up: lodsl;

stosl;

loop up;"
: /* no output */
:"S"(src), "D"(dst) /* input */
:"%ecx", "%eax" ); /* clobbered list */


µ± lodsl ÐÞ¸Ä %eax ʱ£¬lodsl ºÍ stosl Ö¸ÁîÒþº¬µØʹÓÃËü¡£%ecx ¼Ä´æÆ÷Ã÷È·×°Èë count¡£µ« GCC ÔÚÎÒÃÇ֪ͨËüÒÔÇ°ÊDz»ÖªµÀÕâЩµÄ£¬ÎÒÃÇÊÇͨ¹ý½« %eax ºÍ %ecx °üÀ¨ÔÚÐÞÊμĴæÆ÷¼¯ÖÐÀ´Í¨Öª GCC µÄ¡£ÔÚÍê³ÉÕâÒ»²½Ö®Ç°£¬GCC ¼ÙÉè %eax ºÍ %ecx ÊÇ×ÔÓɵģ¬Ëü¿ÉÄܾö¶¨½«ËüÃÇÓÃ×÷´æ´¢ÆäËüµÄÊý¾Ý¡£Çë×¢Ò⣬%esi ºÍ %edi ÓÉ "asm" ʹÓã¬ËüÃDz»ÔÚÐÞÊÎÁбíÖС£ÕâÊÇÒòΪÒѾ­ÉùÃ÷ "asm" ½«ÔÚÊäÈë²Ù×÷ÊýÁбíÖÐʹÓÃËüÃÇ¡£ÕâÀï×îµÍÏÞ¶ÈÊÇ£¬Èç¹ûÔÚ "asm" ÄÚ²¿Ê¹ÓüĴæÆ÷£¨ÎÞÂÛÊÇÃ÷È·»¹ÊÇÒþº¬µØ£©£¬¼È²»³öÏÖÔÚÊäÈë²Ù×÷ÊýÁбíÖУ¬Ò²²»³öÏÖÔÚÊä³ö²Ù×÷ÊýÁбíÖУ¬±ØÐ뽫ËüÁÐΪÐÞÊμĴæÆ÷¡£


½áÊøÓï

×ܵÄÀ´Ëµ£¬ÄÚÁª»ã±à·Ç³£¾Þ´ó£¬ËüÌṩµÄÐí¶àÌØÐÔÎÒÃÇÉõÖÁÔÚÕâÀï¸ù±¾Ã»ÓÐÉæ¼°µ½¡£µ«Èç¹ûÕÆÎÕÁ˱¾ÎÄÃèÊöµÄ»ù±¾²ÄÁÏ£¬ÄúÓ¦¸Ã¿ÉÒÔ¿ªÊ¼¶Ô×Ô¼ºµÄÄÚÁª»ã±à½øÐбàÂëÁË¡£


²Î¿¼×ÊÁÏ

* Äú¿ÉÒÔ²ÎÔı¾ÎÄÔÚ developerWorks È«ÇòÕ¾µãÉÏµÄ Ó¢ÎÄÔ­ÎÄ.

* Çë²Î¿¼ Using and Porting the GNU Compiler Collection (GCC)Êֲᡣ

* Çë²Î¿¼ GNU Assembler (GAS)Êֲᡣ

* ×ÐϸÔĶÁ Brennan's Guide to Inline Assembly¡£


¹ØÓÚ×÷Õß

Bharata B. Rao ÓµÓÐÓ¡¶È Mysore ´óѧµÄµç×ÓºÍͨÐŹ¤³ÌµÄѧʿѧλ¡£Ëû´Ó 1999 Äê¾Í¿ªÊ¼Îª IBM Global Services, India ¹¤×÷ÁË¡£ËûÊÇ IBM Linux ¼¼ÊõÖÐÐĵijÉÔ±Ö®Ò»£¬ËûÔÚ¸ÃÖÐÐÄÖÐÖ÷Òª´ÓÊ Linux RAS£¨¿É¿¿ÐÔ¡¢¿ÉÓÃÐÔºÍÊÊÓÃÐÔ£©µÄÑо¿¡£Ëû¸ÐÐËȤµÄÆäËüÁìÓò°üÀ¨²Ù×÷ϵͳ±¾Öʺʹ¦ÀíÆ÷Ìåϵ½á¹¹¡£¿ÉÒÔͨ¹ý rbharata@in.ibm.com ÓëËûÁªÏµ¡£
ÎÄÕÂÆÀÂÛ

¹²ÓÐ 0 ÌõÆÀÂÛ