作者
luster
摘要:好吧
我們已經鋪墊了很多東西了
而且看上去用匯編寫程序似乎是一個非常恐怖的事情了
不過既然我們感興趣
還是應該開始我們的
hello world
程序
我們開始寫hello world吧
好吧
我們已經鋪墊了很多東西了
而且看上去用匯編寫程序似乎是一個非常恐怖的事情了
不過既然我們感興趣
還是應該開始我們的
hello world
程序
下面的代碼中
我們准備采取直接使用內核中的系統調用的方法
這是調用系統內核服務的最快的方法
我們的代碼不鏈接到其他函數庫
也不使用ELF解釋器
而是直接和內核通訊
我們分別使用nasm和gas兩種匯編器來編譯我們的程序
這樣我們可以看到Intel和AT&T兩種語法格式了
使用的工具
當然首先我們需要匯編編譯器nasm和gas
然後我們需要鏈接器-ld
因為匯編編譯器是生成的只是object代碼
一般的發行包的binutils裡面包括了gas和ld這兩個實用工具
而對於大多數的發行包(例如
Debian
SuSe
Mandrake)都有nasm
Hello
world!
Linux是一個
位的
運行在保護模式下的操作系統
使用的是flat memory 模式
使用ELF格式的二進制代碼
一個程序可以劃分為下面幾個部分
text
data
bss
text是一些只讀的代碼
data是可讀可寫的數據區
bss則是可讀可寫的沒有初始化的數據區
當然可以有其他一些標准的部分
也可以使用戶自己定義的sections
但是我們這裡不關心
一個程序至少有
text部分
下面就是我們的第一個程序
hello
world
我們給出兩個版本
分別是nasm和gas兩種
NASM (hello
asm)
section
data ;section declarationmsg db
Hello
world!
xa ;our dear stringlen equ $
msg ;length of our dear stringsection
text ;
section declaration ;we must export the entry point to the ELF linker
or global _start ;loader
They conventionally recognize _start as their ;
entry point
Use ld
e foo to override the default
_start:;write our string
to stdout mov edx
len ;third argument: message length mov ecx
msg ;second
argument: pointer to message to write mov ebx
;first argument: file handle
(stdout) mov eax
;system call number (sys_write) int
x
;call kernel;
and exit mov ebx
;first syscall argument: exit code mov eax
;system
call number (sys_exit) int
x
;
call kernel
GAS (hello
S)
data # section declarationmsg:
string
Hello
world!
# our dear string len =
msg # length of our dear string
text
# section declaration # we must export the entry point to the ELF linker or
global _start # loader
They conventionally recognize _start as their
# entry point
Use ld
e foo to override the default
_start:
# write our string to stdout movl $len
%edx # third argument:
message length movl $msg
%ecx # second argument: pointer to message to
write movl $
%ebx # first argument: file handle (stdout) movl $
%eax
# system call number (sys_write) int $
x
# call kernel# and exit movl
$
%ebx # first argument: exit code movl $
%eax # system call number
(sys_exit) int $
x
# call kernel
建立可運行的程序
要生成一個可執行的代碼
首先就是用源代碼編譯生產一個object文件
對於nasm
下面的語法
$ nasm
f elf hello
asm
而對於gas
而用下面的語法
$ as
o hello
o hello
S
這樣就得到了hello
o這個object文件了
然後我們就要使用這個object文件來生成可執行代碼
這裡使用鏈接器鏈接
$ ld
s
o hello hello
o
這樣我們就獲得了我們的可以執行的代碼
hello
world
我們的學習就告一段落了
更多的信息可以去參考
by Luster(
cn)
From:http://tw.wingwit.com/Article/program/Oracle/201311/16663.html