linux 下用組合語言編寫的**具有兩種不同的形式。第一種是完全的彙編**,指的是整個程式全部用組合語言編寫。儘管是完全的彙編**,linux 平台下的彙編工具也吸收了 c 語言的長處,使得程式設計師可以使用 #include、#ifdef 等預處理指令,並能夠通過巨集定義來簡化**。第二種是內嵌的彙編**,指的是可以嵌入到c語言程式中的彙編**片段。雖然 ansi 的 c 語言標準中沒有關於內嵌彙編**的相應規定,但各種實際使用的 c 編譯器都做了這方面的擴充,這其中當然就包括 linux 平台下的 gcc。
一 linux彙編語法格式
絕大多數 linux 程式設計師以前只接觸過dos/windows 下的組合語言,這些彙編**都是 intel 風格的。但在 unix 和 linux 系統中,更多採用的還是 at&t 格式,兩者在語法格式上有著很大的不同.
二 hello world的編寫
在 linux 作業系統中,你有很多辦法可以實現在螢幕上顯示乙個字串,但最簡潔的方式是使用 linux 核心提供的系統呼叫。使用這種方法最大的好處是可以直接和作業系統的核心進行通訊,不需要鏈結諸如 libc 這樣的函式庫,也不需要使用 elf 直譯器,因而**尺寸小且執行速度快。
linux 是乙個執行在保護模式下的 32 位作業系統,採用 flat memory 模式,目前最常用到的是 elf 格式的二進位制**。乙個 elf 格式的可執行程式通常劃分為如下幾個部分:.text、.data 和 .bss,其中 .text 是唯讀的**區,.data 是可讀可寫的資料區,而 .bss 則是可讀可寫且沒有初始化的資料區。**區和資料區在 elf 中統稱為 section,根據實際需要你可以使用其它標準的 section,也可以新增自定義 section,但乙個 elf 可執行程式至少應該有乙個 .text 部分。 下面給出我們的第乙個匯程式設計序,用的是 at&t 組合語言格式:
例: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
# 呼叫核心功能
例: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 彙編工具
1.彙編器
彙編器(assembler)的作用是將用組合語言編寫的源程式轉換成二進位制形式的目標**。linux 平台的標準彙編器是 gas,它是 gcc 所依賴的後台彙編工具,通常包含在 binutils 軟體包中。gas 使用標準的 at&t 彙編語法,可以用來彙編用 at&t 格式編寫的程式:
panlu@thinkpad:~/組合語言$ as -o hello.o helloworld.slinux 平台上另乙個經常用到的彙編器是 nasm,它提供了很好的巨集指令功能,並能夠支援相當多的目標**格式,包括 bin、a.out、coff、elf、rdf 等。nasm 採用的是人工編寫的語法分析器,因而執行速度要比 gas 快很多,更重要的是它使用的是 intel 彙編語法,可以用來編譯用 intel 語法格式編寫的匯程式設計序:
panlu@thinkpad:~/組合語言$ nasm -f elf hello.asm2.鏈結器
由彙編器產生的目標**是不能直接在計算機上執行的,它必須經過鏈結器的處理才能生成可執行**。鏈結器通常用來將多個目標**連線成乙個可執行**,這樣可以先將整個程式分成幾個模組來單獨開發,然後才將它們組合(鏈結)成乙個應用程式。 linux 使用 ld 作為標準的鏈結程式,它同樣也包含在 binutils 軟體包中。匯程式設計序在成功通過 gas 或 nasm 的編譯並生成目標**後,就可以使用 ld 將其鏈結成可執行程式了:
panlu@thinkpad:~/組合語言$ ld -s -o hello hello.o3 執行
panlu@thinkpad:~/組合語言$ ./hello四 intel格式hello world!
1、在ubuntu上安裝nasm方法
2、安裝方法:使用如下的命令:
解壓:tar zxvf nasm-2.10.07.tar.gz
進入剛解壓的目錄 cd 解壓後的目錄
然後執行命令:./configure通過以上的步驟nasm就在ubuntu上安裝好了。也可以通過使用命令:nasm -version來檢視是否安裝成功。如果出現了nasm的版本資訊則說明安裝成功,否則還需進一步安裝。make
sudo make install
panlu@thinkpad:~/組合語言$ nasm -version3 編譯執行nasm version 2.10.07 compiled on sep 29 2015
nasm -f elf64(elf32) hello.asm (注意這裡使用elf64還是elf32要看作業系統的位數來決定)輸出hello world便成功了.gcc -o hello hello.o
./hello
素數檢測(組合語言編寫)
兩種方法 方法一 include io32.inc data ts byte please input a number 13,10,0 sc1 byte this is a sushu 13,10,0 sc2 byte this is not a sushu 13,10,0 temp byte 2...
組合語言 AT T組合語言
這兩天的pwn題環境都是在linux中,採用的組合語言是 at t 格式。之前學習的是intel格式的8086彙編,今天學習了下at t組合語言。基於x86 架構的處理器所使用的彙編指令一般有兩種格式 操作intel格式at t格式 暫存器命名 push eax pushl eax 常數 立即運算元...
組合語言編寫中斷的處理程式
cpu都具有執行完當前正在執行的指令之後,檢測到從cpu外部 外中斷 或內部 內中斷 產生的一種特殊資訊,並且可以立即對所接收到的資訊進行處理。稱這樣的資訊為 中斷資訊。cpu有四種情況可以產生中斷資訊 1 除法錯誤 2 單步執行 能夠用來實現debug中一步一步執行程式並返回暫存器狀態的操作 3 ...