日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

att汇编教程 linux,ATT 汇编语法

發(fā)布時間:2023/12/10 linux 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 att汇编教程 linux,ATT 汇编语法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

6 個段寄存器:%cs(code),%ds(data),%ss(stack), %es,%fs,%gs;

3 個控制寄存器:%cr0,%cr2,%cr3;

6 個 debug 寄存器:%db0,%db1,%db2,%db3,%db6,%db7;

2 個測試寄存器:%tr6,%tr7;

8 個浮點寄存器棧:%st(0),%st(1),%st(2),%st(3),%st(4),%st(5),%st(6),

%st(7).

4. 操作數順序

操作數排列是從源(左)到目的(右),如“movl %eax(源), %ebx(目的)”

5, 符號常數

符號常數直接引用 如

value: .long 0x12a3f2de

movl value , %ebx

指令執(zhí)行的結果是將常數 0x12a3f2de 裝入寄存器 ebx。

引用符號地址在符號前加符號$, 如“movl $value, % ebx”則是將符號 value 的地址裝入

寄存器 ebx。

6. 內存引用

Intel 語法的間接內存引用的格式為:

section:[base+index*scale+displacement]

而在 AT&T 語法中對應的形式為:

section:displacement(base,index,scale)

其 中 , base 和 index 是 任 意 的 32-bit base 和 index 寄 存 器 。 scale 可 以 取 值

1,2,4,8。如果不指定 scale 值,則默認值為 1。section 可以指定任意的段寄存器作

為段前 綴,默認的段寄存器在不同的情況下不一樣。如果你在指令中指定了默認的段前綴

則編譯器在目標代碼中不會產生此段前綴代碼。

下面是一些例子:

-4(%ebp) : base=%ebp , displacement=-4 , section 沒 有 指 定 , 由 于 base

=%ebp,所以默認的 section=%ss,index,scale 沒有指定,則 index 為 0。

foo(,%eax,4):index=%eax,scale=4,displacement=foo。其它域沒有指定。這

里默認的 section=%ds。

foo(,1):這個表達式引用的是指針 foo 指向的地址所存放的值。注意這個表達式中沒有

base 和 index,并且只有一個逗號,這是一種異常語法,但卻合法。

%gs:foo:這個表達式引用的是放置于%gs 段里變量 foo 的值。

如果 call 和 jump 操作在操作數前指定前綴“ *”,則表示是一個絕對地址調用/跳轉,也就

是說 jmp/call 指令指定的是一個絕對地址。如果沒有指定"*",則操作數是一個相對地址。

任何指令如果其操作數是一個內存操作,則指令必須指定它的操作尺寸

(byte,word,long),也就是說必須帶有指令后綴(b,w,l)。

1,內聯匯編。

兩種內聯匯編的格式。

一、基本內聯匯編的格式是

__asm__ __volatile__("Instruction List");

二、帶有 C/C++表達式的內聯匯編格式為:

__asm__ __volatile__("Instruction List" : Output : Input : Clobber/Modify);

規(guī)則:

1,這 4 個部分都不是必須的,任何一個部分都可以為空。

2,如 果 Clobber/Modify 為 空 , 則 其 前 面 的 冒 號 (:) 必 須 省 略 。 比 如 __asm__("mov %

%eax, %%ebx" : "=b"(foo) : "a"(inp) : ) 就 是 非 法 的 寫 法 ; 而 __asm__("mov %

%eax, %%ebx" : "=b"(foo) : "a"(inp) )則是正確的。

3,"Instruction List"中的寄存器寫法要遵守相關規(guī)定,比如寄存器前必須使用兩個百分號(%%),

而不是像基本匯編格式一樣在寄存器前只使用一個百分號(%)。比如 __asm__( " mov %%eax, %%ebx" : : );

__asm__( " mov %%eax, %%ebx" : ) 和 __asm__( " mov %eax, %ebx" ) 都 是 正 確 的 寫 法 , 而

__asm__( " mov %eax, %ebx" : : );__asm__( " mov %eax, %ebx" : )和__asm__(

" mov %%eax, %%ebx" )都是錯誤的寫法。

4,區(qū)分一個內聯匯編是基本格式的還是帶有 C/C++表達式格式的,其規(guī)則在于在"Instruction List"后

是否有冒號(:)的存在,如果沒有則是基本格式的,否則,則是帶有 C/C++表達式格式的。

5,ouput:

例子:

int func(void)

{

int b = -1;

__asm__ __volatile__(

"movl $2,%%eax"

:"=a"(b)

);

printf("--------------->%d\n",b);

return 0;

}

我們可以很清楚得看到這個輸出操作由兩部分組成:括號括住 的部分 (b)和引號引

住的部分"=a"。這兩部分都是每一個輸出操作必不可少的。其中括號里面的是c/c++

表達式,而且只能是左值表達式。而右值來自于引用部分。引號中的內容,被稱作

“操作約束”(Operation Constraint),在這個例子中操作約束為"=a",它包含兩個約束:

等號(=)和字母 a,其中等號(=)說明括號中左值表達式b是一個 Write-Only 的,只能夠

被作為當前內聯匯編的輸入,而不能作為輸入。而字母 a 是寄存器 EAX / AX / AL 的

簡寫,說明 cr0 的值要從 eax 寄存器中獲取,也就是說b = eax。

6,input.

理解了output,再來理解input很容易。

__asm__("movl %0, %%db7" : : "a" (cpu->db7));

括號里面的是c/c++表達式,可以是左值,也可以是右值。

引號里面的是寄存器。寄存器作為左值。

總結

以上是生活随笔為你收集整理的att汇编教程 linux,ATT 汇编语法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。