原文在这里:
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的编写吗?
阅读(433) | 评论(0) | 转发(0) |