音影先锋亚洲天堂网|电影世界尽头的爱完整版播放|国产 熟女 91|高清无码免费观看欧美日韩|韩国一区二区三区黄色录像|美女亚洲加勒比在线|亚洲综合网 开心五月|7x成人在线入口|成人网站免费日韩毛片区|国产黄片?一级?二级?三级

匯編語法AT&T與匯編語法Intel的比較

出處:qsqqas 發(fā)布于:2008-09-12 09:24:23

  gcc采用的是AT&T的匯編格式,MS采用Intel的匯編格式.

  一 基本語法

  語法上主要有以下幾個(gè)不同.

  1、寄存器命名原則

  AT&T: %eax

  Intel: eax

  2、源/目的操作數(shù)順序

  AT&T: movl %eax,%ebx

  Intel: mov ebx,eax

  3、常數(shù)/立即數(shù)的格式

  AT&T: movl $_value,%ebx

  Intel: mov eax,_value

  把_value的地址放入eax寄存器

  AT&T: movl $0xd00d,%ebx

  Intel: mov ebx,0xd00d

  4、操作數(shù)長度標(biāo)識(shí)

  AT&T: movw %ax,%bx

  Intel: mov bx,ax

  5、尋址方式

  AT&T: immed32(basepointer,indexpointer,indexscale)

  Intel: [basepointer + indexpointer*indexscale + imm32)

  Linux工作于保護(hù)模式下,用的是32位線性地址,所以在計(jì)算地址時(shí)不用考慮segmentffset的問題.上式中的地址應(yīng)為:

  imm32 + basepointer + indexpointer*indexscale

  下面是一些例子:

  1、直接尋址

  AT&T: _booga ; _booga是一個(gè)全局的C變量

  注意加上$是表示地址引用,不加是表示值引用.

  注:對(duì)于局部變量,可以通過堆棧指針引用.

  Intel: [_booga]

  2、寄存器間接尋址

  AT&T: (%eax)

  Intel: [eax]

  3、變址尋址

  AT&T: _variable(%eax)

  Intel: [eax + _variable]

  AT&T: _array(,%eax,4)

  Intel: [eax*4 + _array]

  AT&T: _array(%ebx,%eax,8)

  Intel: [ebx + eax*8 + _array]

  二 基本的行內(nèi)匯編

  基本的行內(nèi)匯編很簡單,一般是按照下面的格式

  asm("statements");

  例如:

  asm("nop");

  asm("cli");

  asm 和 __asm__是完全一樣的.

  如果有多行匯編,則每一行都要加上 "\n\t"

  例如:

  asm( "pushl %eax\n\t"

  "movl $0,%eax\n\t"

  "popl %eax");

  實(shí)際上gcc在處理匯編時(shí),是要把a(bǔ)sm(...)的內(nèi)容"打印"到匯編文件中,所以格式控制字符是必要的.

  再例如:

  asm("movl %eax,%ebx");

  asm("xorl %ebx,%edx");

  asm("movl $0,_booga);

  在上面的例子中,由于我們?cè)谛袃?nèi)匯編中改變了edx和ebx的值,但是由于gcc的特殊的處理方法,即先形成匯編文件,再交給GAS去匯編,所以GAS并不知道我們已經(jīng)改變了edx和ebx的值,如果程序的上下文需要edx或ebx作暫存,這樣就會(huì)引起嚴(yán)重的后果.對(duì)于變量_booga也存在一樣的問題.為了解決這個(gè)問題,就要用到擴(kuò)展的行內(nèi)匯編語法.

  三 擴(kuò)展的行內(nèi)匯編

  擴(kuò)展的行內(nèi)匯編類似于Watcom.

  基本的格式是:

  asm ( "statements" : output_regs : input_regs : clobbered_regs);

  clobbered_regs指的是被改變的寄存器.

  下面是一個(gè)例子(為方便起見,我使用全局變量):

  int count=1;

  int value=1;

  int buf[10];

  void main()

  {

  asm(

  "cld \n\t"

  "rep \n\t"

  "stosl":: "c" (count), "a" (value) , "D" (buf[0]): "%ecx","%edi" );

  }

  得到的主要匯編代碼為:

  movl count,%ecx

  movl value,%eax

  movl buf,%edi

  #APP

  cld

  rep

  stosl

  #NO_APP

  cld,rep,stos就不用多解釋了.這幾條語句的功能是向buf中寫上count個(gè)value值.冒號(hào)后的語句指明輸入,輸出和被改變的寄存器.通過冒號(hào)以后的語句,編譯器就知道你的指令需要和改變哪些寄存器,從而可以優(yōu)化寄存器的分配.其中符號(hào)"c"(count)指示要把count的值放入ecx寄存器

  類似的還有:

  a eax

  b ebx

  c ecx

  d edx

  S esi

  D edi

  I 常數(shù)值,(0 - 31)

  q,r 動(dòng)態(tài)分配的寄存器

  g eax,ebx,ecx,edx或內(nèi)存變量

  A 把eax和edx合成一個(gè)64位的寄存器(use long longs)

  我們也可以讓gcc自己選擇合適的寄存器.如下面的例子:

  asm("leal (%1,%1,4),%0"

  : "=r" (x)

  : "0" (x) );

  這段代碼實(shí)現(xiàn)5*x的快速乘法.

  得到的主要匯編代碼為:

  movl x,%eax

  #APP

  leal (%eax,%eax,4),%eax

  #NO_APP

  movl %eax,x

  幾點(diǎn)說明:

  1.使用q指示編譯器從eax,ebx,ecx,edx分配寄存器.使用r指示編譯器從eax,ebx,ecx,edx,esi,edi分配寄存器.

  2.我們不必把編譯器分配的寄存器放入改變的寄存器列表,因?yàn)榧拇嫫饕呀?jīng)記住了它們.

  3."="是標(biāo)示輸出寄存器,必須這樣用.

  4.數(shù)字%n的用法:數(shù)字表示的寄存器是按照出現(xiàn)和從左到右的順序映射到用"r"或"q"請(qǐng)求的寄存器.如果我們要重用"r"或"q"請(qǐng)求的寄存器的話,就可以使用它們.

  5.如果強(qiáng)制使用固定的寄存器的話,如不用%1,而用ebx,則

  asm("leal (%%ebx,%%ebx,4),%0"

  : "=r" (x)

  : "0" (x) );

  注意要使用兩個(gè)%,因?yàn)橐粋€(gè)%的語法已經(jīng)被%n用掉了.

  下面可以來解釋letter 4854-4855的問題:

  1、變量加下劃線和雙下劃線有什么特殊含義嗎?加下劃線是指全局變量,但我的gcc中加不加都無所謂.

  2、以上定義用如下調(diào)用時(shí)展開會(huì)是什么意思?

  #define _syscall1(type,name,type1,arg1) \

  type name(type1 arg1) \

  { \

  long __res; \

  /* __res應(yīng)該是一個(gè)全局變量 */

  __asm__ volatile ("int $0x80" \

  /* volatile 的意思是不允許優(yōu)化,使編譯器嚴(yán)格按照你的匯編代碼匯編*/

  : "=a" (__res) \

  /* 產(chǎn)生代碼 movl %eax, __res */

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

  /* 如果我沒記錯(cuò)的話,這里##指的是兩次宏展開.

  即用實(shí)際的系統(tǒng)調(diào)用名字代替"name",然后再把__NR_...展開.

  接著把展開的常數(shù)放入eax,把a(bǔ)rg1放入ebx */

  if (__res >= 0) \

  return (type) __res; \

  errno = -__res; \

  return -1; \

  }

  



  
關(guān)鍵詞:匯編語法AT&T與匯編語法Intel的比較匯編AT&TIntel

版權(quán)與免責(zé)聲明

凡本網(wǎng)注明“出處:維庫電子市場(chǎng)網(wǎng)”的所有作品,版權(quán)均屬于維庫電子市場(chǎng)網(wǎng),轉(zhuǎn)載請(qǐng)必須注明維庫電子市場(chǎng)網(wǎng),http://m.58mhw.cn,違反者本網(wǎng)將追究相關(guān)法律責(zé)任。

本網(wǎng)轉(zhuǎn)載并注明自其它出處的作品,目的在于傳遞更多信息,并不代表本網(wǎng)贊同其觀點(diǎn)或證實(shí)其內(nèi)容的真實(shí)性,不承擔(dān)此類作品侵權(quán)行為的直接責(zé)任及連帶責(zé)任。其他媒體、網(wǎng)站或個(gè)人從本網(wǎng)轉(zhuǎn)載時(shí),必須保留本網(wǎng)注明的作品出處,并自負(fù)版權(quán)等法律責(zé)任。

如涉及作品內(nèi)容、版權(quán)等問題,請(qǐng)?jiān)谧髌钒l(fā)表之日起一周內(nèi)與本網(wǎng)聯(lián)系,否則視為放棄相關(guān)權(quán)利。

廣告
OEM清單文件: OEM清單文件
*公司名:
*聯(lián)系人:
*手機(jī)號(hào)碼:
QQ:
有效期:

掃碼下載APP,
一鍵連接廣大的電子世界。

在線人工客服

買家服務(wù):
賣家服務(wù):
技術(shù)客服:

0571-85317607

網(wǎng)站技術(shù)支持

13606545031

客服在線時(shí)間周一至周五
9:00-17:30

關(guān)注官方微信號(hào),
第一時(shí)間獲取資訊。

建議反饋

聯(lián)系人:

聯(lián)系方式:

按住滑塊,拖拽到最右邊
>>
感謝您向阿庫提出的寶貴意見,您的參與是維庫提升服務(wù)的動(dòng)力!意見一經(jīng)采納,將有感恩紅包奉上哦!