組合語言編寫的Hello World

2021-07-05 12:36:41 字數 3919 閱讀 2961

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.s

linux 平台上另乙個經常用到的彙編器是 nasm,它提供了很好的巨集指令功能,並能夠支援相當多的目標**格式,包括 bin、a.out、coff、elf、rdf 等。nasm 採用的是人工編寫的語法分析器,因而執行速度要比 gas 快很多,更重要的是它使用的是 intel 彙編語法,可以用來編譯用 intel 語法格式編寫的匯程式設計序:

panlu@thinkpad:~/組合語言$ nasm -f elf hello.asm

2.鏈結器

由彙編器產生的目標**是不能直接在計算機上執行的,它必須經過鏈結器的處理才能生成可執行**。鏈結器通常用來將多個目標**連線成乙個可執行**,這樣可以先將整個程式分成幾個模組來單獨開發,然後才將它們組合(鏈結)成乙個應用程式。 linux 使用 ld 作為標準的鏈結程式,它同樣也包含在 binutils 軟體包中。匯程式設計序在成功通過 gas 或 nasm 的編譯並生成目標**後,就可以使用 ld 將其鏈結成可執行程式了:

panlu@thinkpad:~/組合語言$ ld -s -o hello hello.o

3 執行

panlu@thinkpad:~/組合語言$ ./hello

hello world!

四 intel格式

1、在ubuntu上安裝nasm方法

2、安裝方法:使用如下的命令:

解壓:tar zxvf nasm-2.10.07.tar.gz

進入剛解壓的目錄 cd 解壓後的目錄

然後執行命令:./configure

make

sudo make install

通過以上的步驟nasm就在ubuntu上安裝好了。也可以通過使用命令:nasm -version來檢視是否安裝成功。如果出現了nasm的版本資訊則說明安裝成功,否則還需進一步安裝。

panlu@thinkpad:~/組合語言$ nasm -version

nasm version 2.10.07 compiled on sep 29 2015

3 編譯執行

nasm -f elf64(elf32) hello.asm (注意這裡使用elf64還是elf32要看作業系統的位數來決定)

gcc -o hello hello.o

./hello

輸出hello world便成功了.

素數檢測(組合語言編寫)

兩種方法 方法一 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 ...