Chinaunix首页 | 论坛 | 博客
  • 博客访问: 59734
  • 博文数量: 20
  • 博客积分: 1031
  • 博客等级: 少尉
  • 技术积分: 230
  • 用 户 组: 普通用户
  • 注册时间: 2006-08-11 14:22
文章分类

全部博文(20)

文章存档

2011年(2)

2010年(4)

2009年(14)

我的朋友

分类:

2009-09-14 19:39:03

原文在这里:
 
hello.s

 .section .data
 
 .section .text
 
 .globl _start
 
_start:
 
 movl $1, %eax  # this is the linux kernel command
                # number (system call) for exiting
                # a program
 movl $22, %ebx # this is the status number we will
                # return to the operating system.
                # Change this around and it will
                # return different things to
                # echo $?
 int $0x80      # this wakes up the kernel to run
                # the exit command
 
### ### ### ### ### ### ### ### ### ### ### ###
 
编译并执行:
 
1、用汇编器(Assembler)as把汇编程序中的助记符翻译成机器指令,生成目标文件hello.o:
$ as hello.s -o hello.o
 
2、然后用链接器(Linker,或Link Editor)ld把目标文件hello.o链接成可执行文件hello:
$ ld hello.o -o hello

3、执行hello,它只做了一件事,就是退出,退出状态是22,用Shell的特殊变量$?得到它的退出状态:
$ ./hello
$ echo $?
22
 
 
### ### ### ### ### ### ### ### ### ### ### ###
 
问题1:为什么用汇编器将程序翻译成机器指令了还不行,还要有一个链接的步骤呢?

答:
链接主要有两个作用,一是修改目标文件中的信息,对地址做重定位,二是把多个目标文件合并成一个可执行文件
 

### ### ### ### ### ### ### ### ### ### ### ###
 
汇编语言语法、语义:
 
“#”号表示单行注释
 
以“.”开头的词语给汇编器一些特殊指示,称为汇编指示(Assembler Directive)或伪操作(Pseudo-operation)
 
“.section”把代码划分成若干个段(Section),程序被操作系统加载执行时,每个段被加载到不同的地址,操作系统对不同的页面设置不同的读、写、执行权限。“.data”段保存程序的数据,是可读可写的,相当于C程序的全局变量。本程序中没有定义数据,所以“.data”段是空的。
“.section .text”,“.text”段保存代码,是只读和可执行的,后面那些指令都属于“.text”段。

“.globl”指示告诉汇编器,“_start”这个符号要被链接器用到,...
“_start”就像C程序的main函数一样特殊,是整个程序的入口,链接器在链接时会查找目标文件中的“_start”符号代表的地址,把它设置为整个程序的入口地址,所以每个汇编程序都要提供一个“_start”符号并且用“.globl”声明。
 
“_start:”,这里定义了_start符号(上一行“.globl _start”声明了“_start”),汇编器在翻译汇编程序时,当看到这样一个符号定义时,就把它后面一条指令的地址作为这个符号所代表的地址。而“_start”这个符号又比较特殊,它所代表的地址是整个程序的入口地址,所以下一条指令“movl $1, %eax”就成了程序中第一条被执行的指令。
 
“movl $1, %eax”,这是一条数据传送指令,这条指令要求CPU内部产生一个数字1并保存到eax寄存器中。mov的后缀l表示long,说明是32位的传送指令。这条指令不要求CPU读内存,1这个数是在CPU内部产生的,称为立即数(Immediate)。在汇编程序中,立即数前面要加$,寄存器名前面要加%,以便跟符号名区分开。以后我们会看到mov指令还有另外几种形式,但数据传送方向都是一样的,第一个操作数总是源操作数,第二个操作数总是目标操作数。
 
“movl $4, %ebx”,与前一条指令类似,...
 
“int $0x80”,前两条指令都是为这条指令做准备的,...
 
更多精彩,明天继续,^_^
 
### ### ###
 
“int $0x80”,前两条指令都是为这条指令做准备的,这条指令的含义:
 
1、int指令称为软中断指令,执行这条指令后产生一个异常,CPU从用户模式切换到特权模式,然后跳转到内核代码中执行异常处理程序。(这些步骤和中断类似)

2、指令中的立即数0x80是int的一个参数,内核根据这个参数选择不同的异常处理程序,“int $0x80”这条指令指明使用系统调用。用户程序只能通过寄存器传参数给内核,并按内核设计好的异常处理程序运行。

eax的值是系统调用号,内核需要通过eax的值判断用户要调哪个系统调用,_exit的系统调用号是1。ebx的值是传给_exit的参数,表示退出状态。

x86汇编的两种语法:intel语法和AT&T语法
x86汇编一直存在两种不同的语法,在intel的官方文档中使用intel语法,Windows也使用intel语法,而UNIX平台的汇编器一直使用AT&T语法,所以本书使用AT&T语法。movl %edx,%eax这条指令如果用intel语法来写,就是mov eax,edx,...
 
问题2:int是interface的编写吗?
 
阅读(382) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~