• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
  • at&t匯編說明

    發表于:2007-05-26來源:作者:點擊數: 標簽:
    att匯編語法簡單說明這些是從網上的一些資料整理而得,不知道說清楚了沒有,或是有什么錯誤,請指正。1:寄存器引用引用寄存器要在寄存器號前加%,如 mov % eax, % ebx 2: 操作數順序操作數排列是從源(左)到目的(右),如mov % eax(源), % ebx(目的)3:
    at&t匯編說明 rainfall兄作品

    itle: at&t匯編語法簡單說明 這些是從網上的一些資料整理而得,不知道說清楚了沒有,或是有什么錯誤,請指正。 1:寄存器引用 引用寄存器要在寄存器號前加%,如 mov % eax, % ebx 2: 操作數順序 操作數排列是從源(左)到目的(右),如 mov % eax(源), % ebx(目的) 3: 常數/立即數的格式 使用立即數,要在數前面加 $, 如 mov , % ebx
    符號常數直接引用 如 mov value , % ebx (value是一常數,已在前面定義)
    引用符號地址在符號前加 $, 如 mov $value, % ebx (是將value的地址放到ebx中)

    4:操作數的長度
    操作數的長度用加在指令后的符號表示
    b(byte), w(word), l(long) 如 movw %ax,%bx

    5:尋址方式
    內存尋址可以用
    section:disp(base, index, scale) 表示,計算方法是
    base + index*scale + disp, section在實模式下有用,保護模式下用線性地址,不用section。
    例如:
    call *SYMBOL_NAME(sys_call_table)(,% eax,4)
    這是entry.S中的一句,對應應該是
    % eax*4 + sys_call_table, 在sys_call_table中找到相應系統調用的地址。


    二 基本的行內匯編

    基本的行內匯編很簡單,一般是按照下面的格式
    asm("statements");
    例如:asm("nop"); asm("cli");
    asm 和 __asm__是完全一樣的.
    如果有多行匯編,則每一行都要加上 "\n\t"
    例如:
    asm( "pushl % eax\n\t"
    "movl ,% eax\n\t"
    "popl % eax");
    實際上gclearcase/" target="_blank" >cc在處理匯編時,是要把asm(...)的內容"打印"到匯編
    文件中,所以格式控制字符是必要的.

    再例如:
    asm("movl % eax,% ebx");
    asm("xorl % ebx,% edx");
    asm("movl ,_booga);

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

    三 擴展的行內匯編
    基本的格式是:
    asm( statements : outputs : inputs : registers-modified);
    statements是一些匯編語句,outputs是輸出寄存器,inputs是輸入寄存器,registers-modified
    是在這個過程中改變的寄存器。
    例如:

    int i=0, j=1, k=0;
    __asm__ __volatile__("
    pushl %% eax\n
    movl %1, %% eax\n
    addl %2, %% eax\n
    movl %% eax, %0\n
    : "=g" (k)
    : "g" (i), "g" (j)
    ); // k = i + j

    在上面的這段代碼中,輸入寄存器用了"g"限定符,它的意思是將輸入變量放入
    eax,ebx,ecx,edx或內存變量其中之一,類似的限定還有:
    "a" eax
    "b" ebx
    "c" ecx
    "d" edx
    "S" esi
    "D" edi
    "q" 從eax,ebx,ecx,edx分配寄存器
    "r" 從eax,ebx,ecx,edx,esi,edi分配寄存器
    "g" eax,ebx,ecx,edx或內存變量
    "A" 把eax和edx合成一個64位的寄存器(use long longs)
    "I" I是常數值,例如"1",它是把輸出寄存器和輸入寄存器由左到右,由上到下順序往下數對應的寄存器
    在上面這段代碼中,%0對應k存放的寄存器,,%1對應i存放的寄存器,%2對應j存放的寄存器.
    "i" 立即數
    "m" 內存變量
    輸出寄存器要在前面加"=",指示輸出的位置。
    上面的代碼展開大概是:
    mov i, % eax
    mov j, % ebx
    pushl %% eax
    movl % eax, %% eax
    movl % ebx, %% eax
    movl %% eax, % ecx
    popl %% eax

    又如:
    do { \
    int __d0, __d1; \
    __asm__ __volatile__ ("movw %%dx,%%ax\n\t" \
    "movw %4,%%dx\n\t" \
    "movl %% eax,%0\n\t" \
    "movl %% edx,%1" \
    :"=m" (*((long *) (gate_addr))), \
    "=m" (*(1+(long *) (gate_addr))), "=&a" (__d0), "=&d" (__d1) \
    :"i" ((short) (0x8000+(dpl<<13)+(type<<8))), \
    "3" ((char *) (addr)),"2" (__KERNEL_CS << 16)); \
    } while (0)中
    %3 對應edx, %2對應eax, %1是(*(1+(long *) (gate_addr))). 這段代碼是將中斷處理函數的地址填到
    ldt(中斷向量表)中。

    原文轉自:http://www.kjueaiud.com

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>