<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      AT&T 匯編學習

      套用網上看到的一句話開頭吧(這也是我有過的一個過程,基本一樣吧):今天開始學習linux內核編程了,從沒有內核編程基礎開始學起。所以很多相關的知識都要了解。首先就是AT&T匯編語言。因為在linux內核源代碼中,好像除了開始的bootsect.shead.s是用intel的匯編外,別的匯編代碼都是用的AT&T匯編語言,所以有必要把AT&T匯編語言了解一下。

      自己補充一點:我開始沒想過什么linux內核編程哦,只覺得能把內核代碼開懂就是最大的心愿了,不過現在還好,可以開始深入內核編寫一些簡單程序(主要是驅動吧,而且是針對的是嵌入式linux哈)!

      1.學習AT&T匯編語言的理由

      只有一點就是看懂linux啟動代碼。當然以后可能也會用到。

      2.學習的難度

      以為本人intel的匯編學的還算過得去,所以在這基礎之上應該不是太難,最多發半天時間久可以熟悉了吧,對比intel匯編學習。

      3.intel的差異

       

       以下的內容都是AT&T匯編的特點:

      1)、寄存器前面要加“%”,如  mov %eax,%ebx

         這里要注意的一點是,AT&T匯編中,源寄存器和目的寄存器的順序和intel匯編剛好相反,AT&T匯編中,左邊的是源寄存器,右邊的是目的寄存器,在上邊那個例子中,%eax是源寄存器,%ebx是目的寄存器。

       

      2)、立即數/常數前面要加$,如  mov $4,%ebx 4這個數裝入ebx這個寄存器。

         符號常數直接用, 如  mov  value,%eax 即把value代表的那個值裝入eax寄存器。

                           mov $value,%eax 即把value的值作為地址,而把對應那個地址中的值裝入eax。

       

      3)、b(byte):8位, wword):16位, llong):32

         如:  movb %ax,%bx     movw %eax,%ebx

       

      4)、jum/call的操作數前要加上“*"作為前綴, 遠跳轉ljmp,遠調用lcall

         如  ljmp $section,$offset

             lcall $section,$offset

         這里$sectionoffset表示的就是,以section為段地址,offset為段內偏移地址。因此,ljmp $section,$offset即跳轉到section:offset地址。

       

      5)、遠返回lret

         如  lret $stack_adjust

       

      6)、尋址方式

         表示方式 section:disp(base,index,scale)

         計算方法 base+index*scale+disp

              即 section:[base+index*scale+disp]

         其中disp是表示偏移地址。

         如  movl -4(%ebp),%eax  [%ebp-4]的內容裝入eax

       

      7)、C語言中嵌入匯編

         格式: _asm_("asm statements":outputs:inputs:registers-modified)

         其中,"asm statements"是匯編語句表達式,outputs,inputs,register-modified都是可選參數,以冒號隔開,且一次以09編號,如outputs的寄存器是0號,inputs寄存器是1號,往后依次類推。outputs是匯編語句執行完后輸出到的寄存器,inputs是輸入到某個寄存器。

         例1_asm_("pushl %%eax/n/t" "movl $0,%%eax/n/t" "popl %%eax");

         在嵌入匯編中,寄存器前面要加兩個%,因為gcc在編譯是,會先去掉一個%再輸出成匯編格式。

         例2{ register char _res;/

               asm("push %%fs/n/t"

               "movw %%ax,%%fs/n/t"

               "movb %%fs:%2,%%al/n/t"

               "pop %%fs"

               :"=a"(_res):"0"(seg),"m"(*(addr)));/

               _res;}

          movb %%fs:%2,%%al/n/t一句中是把以fs為段地址,以后面的第二號寄存器即后面的seg中的值為偏移地址所對應的值裝入al。"=a"(_res):"0"(seg),"m"(*(addr)))一句中,"=a"(_res)表示把a寄存器中的內容給_res,"0"(seg)表示把seg中的內容給0所對應的寄存器,而0即表示使用和前一個寄存器相同的寄存器,這里即使用a寄存器,也就是說把seg中的內容個a寄存器。

         需要解釋以下的是,a,b,c,d分別表示寄存器eaxebxecxedx

                        SD分別表示寄存器esi,edi

                        r表示任意寄存器

                        0(數字0,不是o?。┍硎臼褂蒙弦粋€寄存器

      4.下面是找到別人翻譯的文檔:

      一 基本語法  

          語法上主要有以下幾個不同.  

      ★ 寄存器命名原則  

      AT&T: %eax Intel: eax  

      ★ 源/目的操作數順序  

      AT&T: movl %eax,%ebx Intel: mov ebx,eax  

      ★ 常數/立即數的格式  

      AT&T: movl $_value,%ebx Intel: mov eax,_value  

      _value的地址放入eax寄存器  

      AT&T: movl $0xd00d,%ebx Intel: mov ebx,0xd00d  

      ★ 操作數長度標識  

      AT&T: movw %ax,%bx Intel: mov bx,ax  

      ★尋址方式  

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

      Intel: [basepointer + indexpointer*indexscale + imm32)  

      Linux工作于保護模式下,用的是32位線性地址,所以在計算地址時  

      不用考慮segment:offset的問題.上式中的地址應為:  

      imm32 + basepointer + indexpointer*indexscale  

      下面是一些例子:  

      ★直接尋址  

      AT&T: _booga ; _booga是一個全局的C變量  

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

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

      Intel: [_booga]  

      ★寄存器間接尋址  

      AT&T: (%eax)  

      Intel: [eax]  

      ★變址尋址  

      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]  

      二 基本的行內匯編  

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

      asm("statements");  

      例如:asm("nop"); asm("cli");  

      asm 和 __asm__是完全一樣的.  

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

      例如:  

      asm( "pushl %eax/n/t"  

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

      "popl %eax");  

      實際上gcc在處理匯編時,是要把asm(...)的內容"打印"到匯編  

      文件中,所以格式控制字符是必要的.  

      再例如:  

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

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

      asm("movl $0,_booga);  

      在上面的例子中,由于我們在行內匯編中改變了edxebx的值,但是由于gcc的特殊的處理方法,即先形成匯編文件,再交給GAS去匯編,所以GAS并不知道我們已經改變了edxebx的值,如果程序的上下文需要edxebx作暫存,這樣就會引起嚴重的后果.對于變量_booga也存在一樣的問題.為了解決這個問題,就要用到擴展的行內匯編語法.  

      三 擴展的行內匯編  

          擴展的行內匯編類似于Watcom.  

      基本的格式是:  

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

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

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

      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中寫上countvalue值.  

      冒號后的語句指明輸入,輸出和被改變的寄存器.  

      通過冒號以后的語句,編譯器就知道你的指令需要和改變哪些寄存器,  

      從而可以優化寄存器的分配.  

      其中符號"c"(count)指示要把count的值放入ecx寄存器  

      類似的還有:  

      a eax  

      b ebx  

      c ecx  

      d edx  

      S esi  

      D edi  

      常數值,(0 - 31)  

      q,r 動態分配的寄存器  

      g eax,ebx,ecx,edx或內存變量  

      eaxedx合成一個64位的寄存器(use long longs)  

      我們也可以讓gcc自己選擇合適的寄存器.  

      如下面的例子:  

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

      :  "=r" (x)  

      posted @ 2010-07-27 00:50  薔薇理想人生  閱讀(3211)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 亚洲国产美女精品久久久| 无码囯产精品一区二区免费| 爱啪啪av导航| 美女一区二区三区在线观看视频| 大方县| 蜜桃亚洲一区二区三区四| 国产极品美女高潮无套| 国产仑乱无码内谢| 伊人狠狠色j香婷婷综合| 亚洲欧美v国产蜜芽tv| 免费观看成人毛片a片| 国产精品三级爽片免费看| 又爆又大又粗又硬又黄的a片| 国产精品免费无遮挡无码永久视频 | 激情六月丁香婷婷四房播| 久久综合九色综合97婷婷| 久久成人国产精品免费软件| 中文字幕国产日韩精品| 国产av无码专区亚洲av软件| 国产色无码专区在线观看| 999精品全免费观看视频| 久热久热中文字幕综合激情| 熟妇人妻av中文字幕老熟妇| 日韩人妻一区中文字幕| 97碰碰碰免费公开在线视频| 亚洲无线码中文字幕在线| 精品无码三级在线观看视频| 国产一区二区不卡91| 免费拍拍拍网站| 亚洲国产精品一二三四五| 亚洲va久久久噜噜噜久久狠狠| 欧美日韩一区二区三区视频播放| 亚洲熟妇丰满多毛xxxx| 精品国产中文字幕在线| √天堂资源网最新版在线| 东京热加勒比无码少妇| 色老99久久九九爱精品| 亚欧乱色精品免费观看| 亚洲精品美女久久久久9999| 成年人尤物视频在线观看| 97在线视频人妻无码|