编译和链接
---------------------
Linux 下两个最主要的汇编器是 Nasm(free, Netwide Assembler)和 GAS(free, Gnu Assembler),
后一个和 GCC 结合在一起. 在这篇文章里我将集中在 Nasm 上, 把 GAS 放在后面,因为它使用 AT&T 的语法, 需要一个长的介绍.
Nasm 调用时应该带上 ELF 格式选项("nasm -f elf hello.asm"); 产生的目标文件用GCC 来链接("gcc hello.o"), 产生最终的 ELF 二进制代码. 下面的这个脚本可用来编译 ASM 的模块; 我尽量把它写得简单, 所以所有它做的就是接受传给它的第一个文件名, 用 Nasm 编译, 用 GCC 来链接.
#!/bin/sh
# assemble.sh =========================================================
outfile=${1%%.*}
tempfile=asmtemp.o
nasm -o $tempfile -f elf $1
gcc $tempfile -o $outfile
rm $tempfile -f
#EOF =================================================================
基本知识:
----------
当然最好的就是在了解系统细节之前从一个例子开始. 这里是一个最基本的"hello-word" 形式的程序:
; asmhello.asm ========================================================
global main
extern printf
section .data
msg db "Helloooooo, nurse!",0Dh,0Ah,0
section .text
main:
push dword msg
call printf
pop eax
ret
; EOF =================================================================
纲要: "global main" 必须声明为全局的(global) -- 并且既然我们用 GCC 来链接,进入点必须以 "main" 来命名 -- 从而装入系统. "extern printf" 只是一个声明,为以后在程序中调用; 注意这是必须的; 参数的大小不需要声明. 我已经把这个例子用标准的 .data, .text 分节, 但这不是严格必须的 -- 可能只需要一个 .text段, 就像在 DOS 下一样.
在代码的主体部分, 你必须把参数压栈来传递给调用. 在 Nasm 里, 你必须声明所有不明确数据的大小; 因此就有 "dword" 这个限定词. 注意和其他汇编器一样,Nasm 假设所有的内存/标号的引用都指的是内存地址或者标号, 而不是它的内容.
因而, 指明字符串 msg 的地址, 你应该使用 push dword msg, 指明字符串 msg 的内容, 应该用 push dword [msg] (这只能包含 msg 的前四个字节). 因为 printf
需要一个指向字符串的指针, 我们应该指明 msg 的地址.
调用 printf 非常的直接. 注意每一次调用后你必须把栈清除(见下); 所以 PUSH 了一个
dword 后, 我从栈里把一个 dword POP 进一个无用的寄存器. Linux 程序只简单的用一个 RET 来返回系统, 由于每个进程都是 shell(或者是 PID)的产物, 所以程序结束后把 控制权还给它.
注意到在 Linux 下, 你是在 "API" 或中断服务的场所里使用系统带来的标准共享库.
所有的外部引用由 GCC 管理, 它给 asm 程序员节省了大部分的工作. 一旦你习惯了基本的技巧, Linux 下的汇编编程实际上要比 DOS 简单的多.
C 调用的语法
--------------------
Linux 使用 C 的调用模式 -- 意味着参数以相反的顺序进栈(最后一个最先), 调用者必须清
除栈. 你可以从栈里把值 pop 出来:
push dword szText
call puts
pop ecx
或者直接修改 ESP:
| 论坛热门帖子: | [lch203] 写得蛮好的linux学习笔记(10-21) [黑马制造] 学习java的30个目标(10-19) [笑傲股林] 做测试半年了,有点迷茫,应该再学些什么提高自己的测试水平和测试能力呢?(10-19) [udp8589] 大家用google的来吱一声? 用百度的~~也来报道下?(10-18) [沂偌掳兆] 本人总结的一些认为C++比较经典的书籍,希望对大家有用(10-18) |
| TAG标签: | 程序设计 汇编 调用 printf dword push 一个 ecx Linux |
注册
个人空间
