亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? linux_asm.txt

?? 基于LINUX操作系統下的各種詳細配置(如FTP
?? TXT
?? 第 1 頁 / 共 2 頁
字號:
一、簡介

作為最基本的編程語言之一,匯編語言雖然應用的范圍不算很廣,但重要性卻勿庸置疑,因為它能夠完成許多其它語言所無法完成的功能。就拿 Linux 內核來講,雖然絕大部分代碼是用 C 語言編寫的,但仍然不可避免地在某些關鍵地方使用了匯編代碼,其中主要是在 Linux 的啟動部分。由于這部分代碼與硬件的關系非常密切,即使是 C 語言也會有些力不從心,而匯編語言則能夠很好揚長避短,最大限度地發揮硬件的性能。

大多數情況下 Linux 程序員不需要使用匯編語言,因為即便是硬件驅動這樣的底層程序在 Linux 操作系統中也可以用完全用 C 語言來實現,再加上 GCC 這一優秀的編譯器目前已經能夠對最終生成的代碼進行很好的優化,的確有足夠的理由讓我們可以暫時將匯編語言拋在一邊了。但實現情況是 Linux 程序員有時還是需要使用匯編,或者不得不使用匯編,理由很簡單:精簡、高效和 libc 無關性。假設要移植 Linux 到某一特定的嵌入式硬件環境下,首先必然面臨如何減少系統大小、提高執行效率等問題,此時或許只有匯編語言能幫上忙了。

匯編語言直接同計算機的底層軟件甚至硬件進行交互,它具有如下一些優點:


能夠直接訪問與硬件相關的存儲器或 I/O 端口; 
能夠不受編譯器的限制,對生成的二進制代碼進行完全的控制; 
能夠對關鍵代碼進行更準確的控制,避免因線程共同訪問或者硬件設備共享引起的死鎖; 
能夠根據特定的應用對代碼做最佳的優化,提高運行速度; 
能夠最大限度地發揮硬件的功能。 

同時還應該認識到,匯編語言是一種層次非常低的語言,它僅僅高于直接手工編寫二進制的機器指令碼,因此不可避免地存在一些缺點:


編寫的代碼非常難懂,不好維護; 
很容易產生 bug,難于調試; 
只能針對特定的體系結構和處理器進行優化; 
開發效率很低,時間長且單調。 

Linux 下用匯編語言編寫的代碼具有兩種不同的形式。第一種是完全的匯編代碼,指的是整個程序全部用匯編語言編寫。盡管是完全的匯編代碼,Linux 平臺下的匯編工具也吸收了 C 語言的長處,使得程序員可以使用 #include、#ifdef 等預處理指令,并能夠通過宏定義來簡化代碼。第二種是內嵌的匯編代碼,指的是可以嵌入到C語言程序中的匯編代碼片段。雖然 ANSI 的 C 語言標準中沒有關于內嵌匯編代碼的相應規定,但各種實際使用的 C 編譯器都做了這方面的擴充,這其中當然就包括 Linux 平臺下的 GCC。

二、Linux 匯編語法格式

絕大多數 Linux 程序員以前只接觸過DOS/Windows 下的匯編語言,這些匯編代碼都是 Intel 風格的。但在 Unix 和 Linux 系統中,更多采用的還是 AT&T 格式,兩者在語法格式上有著很大的不同:


在 AT&T 匯編格式中,寄存器名要加上 '%' 作為前綴;而在 Intel 匯編格式中,寄存器名不需要加前綴。例如:

AT&T 格式  pushl %eax
Intel 格式 push eax 


在 AT&T 匯編格式中,用 '$' 前綴表示一個立即操作數;而在 Intel 匯編格式中,立即數的表示不用帶任何前綴。例如:

AT&T 格式 pushl $1 
Intel 格式 push 1 


AT&T 和 Intel 格式中的源操作數和目標操作數的位置正好相反。在 Intel 匯編格式中,目標操作數在源操作數的左邊;而在 AT&T 匯編格式中,目標操作數在源操作數的右邊。例如:

AT&T 格式 addl $1, %eax 
Intel 格式 add eax, 1 


在 AT&T 匯編格式中,操作數的字長由操作符的最后一個字母決定,后綴'b'、'w'、'l'分別表示操作數為字節(byte,8 比特)、字(word,16 比特)和長字(long,32比特);而在 Intel 匯編格式中,操作數的字長是用 "byte ptr" 和 "word ptr" 等前綴來表示的。例如:

AT&T 格式 
movb val, %al 
Intel 格式 mov al, byte ptr val 

在 AT&T 匯編格式中,絕對轉移和調用指令(jump/call)的操作數前要加上'*'作為前綴,而在 Intel 格式中則不需要。 
遠程轉移指令和遠程子調用指令的操作碼,在 AT&T 匯編格式中為 "ljump" 和 "lcall",而在 Intel 匯編格式中則為 "jmp far" 和 "call far",即:

AT&T 格式 ljump $section, $offset     lcall $section, $offset 
Intel 格式 jmp far sectionffset     call far sectionffset 


與之相應的遠程返回指令則為:

AT&T 格式 lret $stack_adjust 
Intel 格式 ret far stack_adjust 


在 AT&T 匯編格式中,內存操作數的尋址方式是


section:disp(base, index, scale)



而在 Intel 匯編格式中,內存操作數的尋址方式為:


section:[base + index*scale + disp]



由于 Linux 工作在保護模式下,用的是 32 位線性地址,所以在計算地址時不用考慮段基址和偏移量,而是采用如下的地址計算方法:


disp + base + index * scale



下面是一些內存操作數的例子:

AT&T 格式                         Intel 格式 
movl -4(%ebp), %eax               mov eax, [ebp - 4] 
movl array(, %eax, 4), %eax       mov eax, [eax*4 + array] 
movw array(%ebx, %eax, 4), %cx    mov cx, [ebx + 4*eax + array] 
movb $4, %fs%eax)               mov fs:eax, 4 



三、Hello World!

真不知道打破這個傳統會帶來什么樣的后果,但既然所有程序設計語言的第一個例子都是在屏幕上打印一個字符串 "Hello World!",那我們也以這種方式來開始介紹 Linux 下的匯編語言程序設計。

在 Linux 操作系統中,你有很多辦法可以實現在屏幕上顯示一個字符串,但最簡潔的方式是使用 Linux 內核提供的系統調用。使用這種方法最大的好處是可以直接和操作系統的內核進行通訊,不需要鏈接諸如 libc 這樣的函數庫,也不需要使用 ELF 解釋器,因而代碼尺寸小且執行速度快。

Linux 是一個運行在保護模式下的 32 位操作系統,采用 flat memory 模式,目前最常用到的是 ELF 格式的二進制代碼。一個 ELF 格式的可執行程序通常劃分為如下幾個部分:.text、.data 和 .bss,其中 .text 是只讀的代碼區,.data 是可讀可寫的數據區,而 .bss 則是可讀可寫且沒有初始化的數據區。代碼區和數據區在 ELF 中統稱為 section,根據實際需要你可以使用其它標準的 section,也可以添加自定義 section,但一個 ELF 可執行程序至少應該有一個 .text 部分。下面給出我們的第一個匯編程序,用的是 AT&T 匯編語言格式:

例1. AT&T 格式


#hello.s 
.data                    # 數據段聲明
        msg : .string "Hello, world!\\n" # 要輸出的字符串
        len = . - msg                   # 字串長度

.text                    # 代碼段聲明
.global _start           # 指定入口函數
        
_start:                  # 在屏幕上顯示一個字符串
        movl $len, %edx  # 參數三:字符串長度
        movl $msg, %ecx  # 參數二:要顯示的字符串
        movl $1, %ebx    # 參數一:文件描述符(stdout) 
        movl $4, %eax    # 系統調用號(sys_write) 
        int  $0x80       # 調用內核功能
        
                         # 退出程序
        movl $0,%ebx     # 參數一:退出代碼
        movl $1,%eax     # 系統調用號(sys_exit) 
        int  $0x80       # 調用內核功能



初次接觸到 AT&T 格式的匯編代碼時,很多程序員都認為太晦澀難懂了,沒有關系,在 Linux 平臺上你同樣可以使用 Intel 格式來編寫匯編程序:

例2. Intel 格式



; hello.asm 
section .data            ; 數據段聲明
        msg db "Hello, world!", 0xA     ; 要輸出的字符串
        len equ $ - msg                 ; 字串長度

section .text            ; 代碼段聲明
global _start            ; 指定入口函數

_start:                  ; 在屏幕上顯示一個字符串
        mov edx, len     ; 參數三:字符串長度
        mov ecx, msg     ; 參數二:要顯示的字符串
        mov ebx, 1       ; 參數一:文件描述符(stdout) 
        mov eax, 4       ; 系統調用號(sys_write) 
        int 0x80         ; 調用內核功能

                         ; 退出程序
        mov ebx, 0       ; 參數一:退出代碼
        mov eax, 1       ; 系統調用號(sys_exit) 
        int 0x80         ; 調用內核功能



上面兩個匯編程序采用的語法雖然完全不同,但功能卻都是調用 Linux 內核提供的 sys_write 來顯示一個字符串,然后再調用 sys_exit 退出程序。在 Linux 內核源文件 include/asm-i386/unistd.h 中,可以找到所有系統調用的定義。

四、Linux 匯編工具

Linux 平臺下的匯編工具雖然種類很多,但同 DOS/Windows 一樣,最基本的仍然是匯編器、連接器和調試器。

1.匯編器

匯編器(assembler)的作用是將用匯編語言編寫的源程序轉換成二進制形式的目標代碼。Linux 平臺的標準匯編器是 GAS,它是 GCC 所依賴的后臺匯編工具,通常包含在 binutils 軟件包中。GAS 使用標準的 AT&T 匯編語法,可以用來匯編用 AT&T 格式編寫的程序:


[xiaowp@gary code]$ as -o hello.o hello.s



Linux 平臺上另一個經常用到的匯編器是 NASM,它提供了很好的宏指令功能,并能夠支持相當多的目標代碼格式,包括 bin、a.out、coff、elf、rdf 等。NASM 采用的是人工編寫的語法分析器,因而執行速度要比 GAS 快很多,更重要的是它使用的是 Intel 匯編語法,可以用來編譯用 Intel 語法格式編寫的匯編程序:


[xiaowp@gary code]$ nasm -f elf hello.asm



2.鏈接器

由匯編器產生的目標代碼是不能直接在計算機上運行的,它必須經過鏈接器的處理才能生成可執行代碼。鏈接器通常用來將多個目標代碼連接成一個可執行代碼,這樣可以先將整個程序分成幾個模塊來單獨開發,然后才將它們組合(鏈接)成一個應用程序。 Linux 使用 ld 作為標準的鏈接程序,它同樣也包含在 binutils 軟件包中。匯編程序在成功通過 GAS 或 NASM 的編譯并生成目標代碼后,就可以使用 ld 將其鏈接成可執行程序了:


[xiaowp@gary code]$ ld -s -o hello hello.o



3.調試器

有人說程序不是編出來而是調出來的,足見調試在軟件開發中的重要作用,在用匯編語言編寫程序時尤其如此。Linux 下調試匯編代碼既可以用 GDB、DDD 這類通用的調試器,也可以使用專門用來調試匯編代碼的 ALD(Assembly Language Debugger)。

從調試的角度來看,使用 GAS 的好處是可以在生成的目標代碼中包含符號表(symbol table),這樣就可以使用 GDB 和 DDD 來進行源碼級的調試了。要在生成的可執行程序中包含符號表,可以采用下面的方式進行編譯和鏈接:


[xiaowp@gary code]$ as --gstabs -o hello.o hello.s
[xiaowp@gary code]$ ld -o hello hello.o



執行 as 命令時帶上參數 --gstabs 可以告訴匯編器在生成的目標代碼中加上符號表,同時需要注意的是,在用 ld 命令進行鏈接時不要加上 -s 參數,否則目標代碼中的符號表在鏈接時將被刪去。

在 GDB 和 DDD 中調試匯編代碼和調試 C 語言代碼是一樣的,你可以通過設置斷點來中斷程序的運行,查看變量和寄存器的當前值,并可以對代碼進行單步跟蹤。


圖1 用 DDD 中調試匯編程序

匯編程序員通常面對的都是一些比較苛刻的軟硬件環境,短小精悍的ALD可能更能符合實際的需要,因此下面主要介紹一下如何用ALD來調試匯編程序。首先在命令行方式下執行ald命令來啟動調試器,該命令的參數是將要被調試的可執行程序:


[xiaowp@gary doc]$ ald hello
Assembly Language Debugger 0.1.3
Copyright (C) 2000-2002 Patrick Alken

hello: ELF Intel 80386 (32 bit), LSB, Executable, Version 1 (current)
Loading debugging symbols...(15 symbols loaded)
ald>;



當 ALD 的提示符出現之后,用 disassemble 命令對代碼段進行反匯編:


ald>; disassemble -s .text
Disassembling section .text (0x08048074 - 0x08048096)
08048074  BA0F000000                 mov edx, 0xf
08048079  B998900408                 mov ecx, 0x8049098
0804807E  BB01000000                 mov ebx, 0x1
08048083  B804000000                 mov eax, 0x4
08048088  CD80                       int 0x80
0804808A  BB00000000                 mov ebx, 0x0
0804808F  B801000000                 mov eax, 0x1
08048094  CD80                       int 0x80



上述輸出信息的第一列是指令對應的地址碼,利用它可以設置在程序執行時的斷點:


?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
国产老肥熟一区二区三区| 日韩你懂的电影在线观看| 6080午夜不卡| 国产精品二区一区二区aⅴ污介绍| 亚洲国产成人91porn| 福利91精品一区二区三区| 欧美日韩国产中文| 亚洲视频你懂的| 国内成人免费视频| 欧美一级高清片| 亚洲国产精品尤物yw在线观看| 国产 欧美在线| 日韩精品一区在线| 日本女人一区二区三区| 日本黄色一区二区| 国产精品你懂的在线欣赏| 国产在线播放一区| 91精品国产黑色紧身裤美女| 亚洲影视在线观看| 色屁屁一区二区| 亚洲日本乱码在线观看| 9人人澡人人爽人人精品| 久久精品人人爽人人爽| 国产在线国偷精品免费看| 欧美一卡二卡三卡| 日本一区中文字幕| 欧美精品久久久久久久多人混战 | 成人午夜激情片| 久久精品一区二区三区不卡| 久久精品国产精品亚洲红杏| 欧美疯狂做受xxxx富婆| 天堂成人免费av电影一区| 欧美日韩一区二区三区四区| 亚洲丰满少妇videoshd| 欧美日韩中字一区| 婷婷夜色潮精品综合在线| 日韩一区二区视频| 激情另类小说区图片区视频区| 日韩视频国产视频| 国产一区二区电影| 亚洲国产成人自拍| 91免费观看国产| 亚洲一区在线视频观看| 欧美日本不卡视频| 另类欧美日韩国产在线| 久久久综合精品| 91网站黄www| 午夜精品久久久久久久99樱桃| 欧美日韩和欧美的一区二区| 麻豆成人免费电影| 国产嫩草影院久久久久| 色琪琪一区二区三区亚洲区| 亚洲高清不卡在线观看| 欧美成人一区二区| 懂色av中文一区二区三区| 日韩毛片在线免费观看| 91精品免费观看| 国产馆精品极品| 亚洲综合久久久久| 久久综合久久综合亚洲| 91性感美女视频| 日韩国产一二三区| 国产日韩欧美激情| 欧美特级限制片免费在线观看| 免费日本视频一区| 亚洲天堂a在线| 欧美成人性战久久| 色综合久久九月婷婷色综合| 日韩av中文在线观看| 欧美国产丝袜视频| 91精品欧美综合在线观看最新| 国产酒店精品激情| 亚洲成人动漫在线免费观看| 久久综合av免费| 欧美优质美女网站| 国产黑丝在线一区二区三区| 亚洲国产日韩在线一区模特| 久久青草国产手机看片福利盒子| 在线亚洲一区二区| 风间由美一区二区av101| 亚洲成av人片一区二区| 中日韩免费视频中文字幕| 91 com成人网| 91小视频在线观看| 国产酒店精品激情| 日韩av不卡在线观看| 亚洲人亚洲人成电影网站色| 日韩欧美国产系列| 欧美喷潮久久久xxxxx| 99这里只有精品| 国产一二三精品| 日本va欧美va精品发布| 日本网站在线观看一区二区三区| 中文字幕的久久| 久久婷婷综合激情| 日韩一级成人av| 欧美日韩一区在线| 91天堂素人约啪| 成人亚洲一区二区一| 国产老妇另类xxxxx| 国精产品一区一区三区mba视频| 亚洲国产日韩一级| 亚洲精品乱码久久久久久久久| 欧美激情在线观看视频免费| 欧美成人激情免费网| 欧美一区二区播放| 欧美一区二区三区四区在线观看 | 久久综合成人精品亚洲另类欧美 | 综合久久久久久| 国产免费观看久久| 久久久精品免费免费| 欧美精品一区二区三区高清aⅴ | 人人超碰91尤物精品国产| 亚洲午夜激情av| 亚洲国产一二三| 日韩制服丝袜先锋影音| 国产一区二区三区综合| 国产在线精品国自产拍免费| 精品一区二区三区在线视频| 另类中文字幕网| 国产精品一区二区91| 丰满少妇在线播放bd日韩电影| 国产成人免费视频一区| 成人美女视频在线观看| 91浏览器打开| 欧美视频在线播放| 日韩一级视频免费观看在线| 欧美videos中文字幕| 中文一区二区完整视频在线观看| 亚洲欧美自拍偷拍| 亚洲国产精品一区二区尤物区| 日韩电影在线免费观看| 国内成+人亚洲+欧美+综合在线| 国产激情一区二区三区桃花岛亚洲| 国产99精品国产| 91一区二区在线| 91精品久久久久久久99蜜桃 | 国产美女娇喘av呻吟久久| 国产精品99久久久久久有的能看| 福利视频网站一区二区三区| av在线一区二区三区| 欧洲一区二区av| 欧美成人在线直播| 国产精品美女久久久久久久久久久 | 国产ts人妖一区二区| 91视频你懂的| 中文字幕免费在线观看视频一区| 国产精品国产精品国产专区不片| 一区二区三区在线视频观看58| 奇米影视在线99精品| 成人av电影在线网| 911精品国产一区二区在线| 国产三级久久久| 亚洲妇女屁股眼交7| 国产一区二区三区免费看| 在线一区二区视频| 国产日韩精品一区二区三区| 一区二区三区久久久| 国产成人精品免费在线| 在线观看91精品国产麻豆| 中文字幕一区不卡| 国产在线视频精品一区| 在线欧美日韩精品| 欧美国产激情一区二区三区蜜月 | 国产夫妻精品视频| 欧美伦理视频网站| 国产精品国产精品国产专区不蜜| 奇米亚洲午夜久久精品| 色综合欧美在线视频区| 久久综合丝袜日本网| 日韩精品每日更新| 91麻豆免费在线观看| 久久蜜桃av一区二区天堂| 青青草97国产精品免费观看无弹窗版 | 国产中文字幕精品| 欧美日韩在线观看一区二区 | 精品国产自在久精品国产| 亚洲综合成人在线视频| 成人黄色大片在线观看| 久久久综合视频| 国产自产v一区二区三区c| 91.麻豆视频| 亚洲成人av一区| 色综合色狠狠天天综合色| 国产精品看片你懂得| 国产高清久久久久| 久久亚洲一区二区三区明星换脸| 午夜精品久久久| 欧美羞羞免费网站| 亚洲激情中文1区| 色综合久久中文综合久久牛| 欧美激情一区二区| 国产不卡高清在线观看视频| 久久综合一区二区| 国产成人久久精品77777最新版本| 日韩你懂的电影在线观看| 青青国产91久久久久久| 欧美精品乱人伦久久久久久| 亚洲成a人v欧美综合天堂| 欧美久久一区二区|