.section .data
.section .text
.globl _start
_start:
movl $1,%eax
movl $4,%ebx
int $0x80
汇编程序中以. 开头的名称并不是指令助记符,不会被翻译成机器指令,而是给汇编器一些特殊指示,称为汇编指示(assembler directive)或者,称为伪操作
语句中:
.section指示把代码划分为若干段。程序在执行时,每个段被加载到不同的地址。
.data 段保存程序的数据,是可读可写的,相当与c语言中的全局变量。
.text 段用来保存代码,是可读和可执行的,本程序中后面的指令都是在.text段的。
_start 是一个符号,符号在汇编程序中代表一个地址,可以用杂指令中,汇编程序禁
经过汇编器的处理后,所有的符号都被替换成它所代表的地址值。
.globl 告示汇编器,_start 这个符号要被连接器用到,所以要在目标文件中笔记它是
一个全局变量,_start 就像是c程序中的main憾事一样的特殊,是整个程序的入口,连接器在连接时会查找目标文件中的_start 符号代表的地址,同时会把它设置成整个程序的入口。
movl $1,%eax
这是一条数据传送指令,要求cpu内部产生一个数字1,并保存到eax寄存器中,mov的后缀l表示long,说明是32位的传送指令,1是立即数(立即数前面要加上$,寄存器前面要加上%,以便和符号名相区分开。)
int $0x80
int 指令是软中断指令,可以用这条指令故意产生一个异常。0x80是参数,在异常处理中,这个参数来决定如何的处理。
eax 的值是系统调用号。
x86的寄存器:
eax,ebx,ecx,edx,edi,esi------通用寄存器
除法指令中的被除数要放在eax中,edx中必须是0,而商数要放在eax中,余数要保存在edx中。
ebp,esp,eip,eflags-----特殊寄存器
eip是程序计数器,eflags保存着计算机中产生的标志位。
而,ebp和esp用于维护函数调用的栈桢。
.section .data
data_items:
.long 3,67,34,222,45,75,54,34,44,33,22,11,66,0
.section .text
.globl _start
_start:
movl $0,%edi #move 0 into the index register
movl data_items(,%edi,4),%eax #load the first byte of data
movl %eax ,%ebx #since this is the first iten ,%eax is th biggest
start_loop:
cmpl $0,%eax
je loop_exit
incl %edi
movl data_items(,%edi,4),%eax
cmpl %ebx,%eax
jle start_loop
movl %eax,%ebx
jmp start_loop
loop_exit:
movl $1,%eax
int $0x80
这段汇编中:
.long 声明一组数,每个数占32位
其中的data_items 相当与c语言中的数组名,汇编会把数组的首地址作为data_items
符号所代表的地址。
除了.long外,常用的数据申明还有;
.byte 申明一组数,每个数占8位
.ascii 例如: .ascii "hello world",取值为相应字符的ascii码,和c语言不同
的是,这样的申明字符串末尾是没有'/0'的。
edi 寄存器保存数组中的当前位置,每次比较完后酒吧edi的值加1
并指向下一个数
movl data_items(,%edi,4),%eax
把数组的第0个元素送到eax寄存器中,data_items 是数组地址,edi是数组的下标,4
表示每个元素占4个字节
cmpl $0 ,%eax
比较eax的值是不是0,如果是0 ,就说明到达数组的末尾了,要跳出循环。
cmpl指令将两个操作数相减,但不保存计算结果,只是根据结果改变
eflags寄存器的标志位。如果相等:
ZF位置1
je 是个条件跳转指令,它会检察eflags中的ZF位,如果为1的话,跳转,否则不跳转。
je------jump if equal
incl %edi
movl data_items(,%edi,4),%eax
将edi的值加1,把数组中的下一个数传送到eax寄存器中。
cmpl %ebx,%eax
jle start_loop
把前数组元素eax和当前为止找到的最大值ebx做比较,如果前者小于后者,则最大值
没有变。循环
jle-----jump if less than or equal
jmp 是一个无条件跳转指令,什么条件也不判断,直接跳转。
x86中的寻址方式---addressing mode
通用格式:
address_or_offset(%base_or_offset,%index,multiplier)
它所表示的地址可以这样的计算出来:
final addrsee=address_or_offset+base_or_offset+multiplier*index
其中,address_or_offset和multiplier 必须是常数,base_or_offset和index
必须是寄存器。
1:直接寻址--direct addressing mode,只使用address_or_offset 寻址,例如
movl address,%eax-----把address处的32位数传送到eax寄存器中。
2:变址寻址--index addressing mode,例如:
movl data_items(,%edi,4),%eax,用于访问数组元素比较的方便。
3:间接寻址--indirect addressing mode ,只使用base_or_offset寻址,
movl (%eax),%ebx--把%eax寄存器的值看作地址,把内存中这个地址处的32为数
传送到eax寄存器中。
4:基址寻址--base pointer addressing mode 只使用addrsee——or_offset 和base_or
_offset寻址。
movl 4(%eax),%ebx---用与访问结构体比较的方便。其中eax表示结构的基地址,
其中的一个成员在结构体中的偏移量是4字节。用这条指令可以比较的方便的读取
这个成员。
5:立即数寻址--immediate mode
movl $12,%eax
6:寄存器寻址--register addressing mode,就是指令中有一个操作数是寄存器。
ELF文件
该文件格式是unix中开放的标准。
分为L
可重定位的目标文件
可执行文件
共享库
readelf:命令---Displays information about ELF files.
hexdump:命令---The hexdump utility is a filter which displays the specified
files, orthe standard input, if no files are specified, in a user specif
ied for mat.
[yskcg@yskcg workc]$ readelf -a maxnum.o
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: REL (Relocatable file)
Machine: Intel 80386
Version: 0x1
Entry point address: 0x0
Start of program headers: 0 (bytes into file)
Start of section headers: 200 (bytes into file)
Flags: 0x0
Size of this header: 52 (bytes)
Size of program headers: 0 (bytes)
Number of program headers: 0
Size of section headers: 40 (bytes)
Number of section headers: 8
Section header string table index: 5
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .text PROGBITS 00000000 000034 000062 00 AX 0 0 4
[ 2] .rel.text REL 00000000 0002b0 000010 08 6 1 4
[ 3] .data PROGBITS 00000000 000098 000000 00 WA 0 0 4
[ 4] .bss NOBITS 00000000 000098 000000 00 WA 0 0 4
[ 5] .shstrtab STRTAB 00000000 000098 000030 00 0 0 1
[ 6] .symtab SYMTAB 00000000 000208 000080 10 7 7 4
[ 7] .strtab STRTAB 00000000 000288 000028 00 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings)
I (info), L (link order), G (group), x (unknown)
O (extra OS processing required) o (OS specific), p (processor specific)
There are no section groups in this file.
There are no program headers in this file.
Relocation section '.rel.text' at offset 0x2b0 contains 2 entries:
Offset Info Type Sym.Value Sym. Name
00000040 00000101 R_386_32 00000000 .text
0000004f 00000101 R_386_32 00000000 .text
There are no unwind sections in this file.
Symbol table '.symtab' contains 8 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
1: 00000000 0 SECTION LOCAL DEFAULT 1
2: 00000000 0 SECTION LOCAL DEFAULT 3
3: 00000000 0 SECTION LOCAL DEFAULT 4
4: 00000000 0 NOTYPE LOCAL DEFAULT 1 data_items
5: 00000046 0 NOTYPE LOCAL DEFAULT 1 start_loop
6: 0000005b 0 NOTYPE LOCAL DEFAULT 1 loop_exit
7: 00000038 0 NOTYPE GLOBAL DEFAULT 1 _start
No version information found in this file.
[yskcg@yskcg workc]$ man hexdump
[yskcg@yskcg workc]$ hexdump -C maxnum.o
00000000 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 |.ELF............|
00000010 01 00 03 00 01 00 00 00 00 00 00 00 00 00 00 00 |................|
00000020 c8 00 00 00 00 00 00 00 34 00 00 00 00 00 28 00 |........4.....(.|
00000030 08 00 05 00 03 00 00 00 43 00 00 00 22 00 00 00 |........C..."...|
00000040 de 00 00 00 2d 00 00 00 4b 00 00 00 36 00 00 00 |....-...K...6...|
00000050 22 00 00 00 2c 00 00 00 21 00 00 00 16 00 00 00 |"...,...!.......|
00000060 0b 00 00 00 42 00 00 00 00 00 00 00 bf 00 00 00 |....B...........|
00000070 00 8b 04 bd 00 00 00 00 89 c3 83 f8 00 74 10 47 |.............t.G|
00000080 8b 04 bd 00 00 00 00 39 d8 7e ef 89 c3 eb eb b8 |.......9.~......|
00000090 01 00 00 00 cd 80 00 00 00 2e 73 79 6d 74 61 62 |..........symtab|
000000a0 00 2e 73 74 72 74 61 62 00 2e 73 68 73 74 72 74 |..strtab..shstrt|
000000b0 61 62 00 2e 72 65 6c 2e 74 65 78 74 00 2e 64 61 |ab..rel.text..da|
000000c0 74 61 00 2e 62 73 73 00 00 00 00 00 00 00 00 00 |ta..bss.........|
000000d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
000000f0 1f 00 00 00 01 00 00 00 06 00 00 00 00 00 00 00 |................|
00000100 34 00 00 00 62 00 00 00 00 00 00 00 00 00 00 00 |4...b...........|
00000110 04 00 00 00 00 00 00 00 1b 00 00 00 09 00 00 00 |................|
00000120 00 00 00 00 00 00 00 00 b0 02 00 00 10 00 00 00 |................|
00000130 06 00 00 00 01 00 00 00 04 00 00 00 08 00 00 00 |................|
00000140 25 00 00 00 01 00 00 00 03 00 00 00 00 00 00 00 |%...............|
00000150 98 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000160 04 00 00 00 00 00 00 00 2b 00 00 00 08 00 00 00 |........+.......|
00000170 03 00 00 00 00 00 00 00 98 00 00 00 00 00 00 00 |................|
00000180 00 00 00 00 00 00 00 00 04 00 00 00 00 00 00 00 |................|
00000190 11 00 00 00 03 00 00 00 00 00 00 00 00 00 00 00 |................|
000001a0 98 00 00 00 30 00 00 00 00 00 00 00 00 00 00 00 |....0...........|
000001b0 01 00 00 00 00 00 00 00 01 00 00 00 02 00 00 00 |................|
000001c0 00 00 00 00 00 00 00 00 08 02 00 00 80 00 00 00 |................|
000001d0 07 00 00 00 07 00 00 00 04 00 00 00 10 00 00 00 |................|
000001e0 09 00 00 00 03 00 00 00 00 00 00 00 00 00 00 00 |................|
000001f0 88 02 00 00 28 00 00 00 00 00 00 00 00 00 00 00 |....(...........|
00000200 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000210 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000220 00 00 00 00 03 00 01 00 00 00 00 00 00 00 00 00 |................|
00000230 00 00 00 00 03 00 03 00 00 00 00 00 00 00 00 00 |................|
00000240 00 00 00 00 03 00 04 00 01 00 00 00 00 00 00 00 |................|
00000250 00 00 00 00 00 00 01 00 0c 00 00 00 46 00 00 00 |............F...|
00000260 00 00 00 00 00 00 01 00 17 00 00 00 5b 00 00 00 |............[...|
00000270 00 00 00 00 00 00 01 00 21 00 00 00 38 00 00 00 |........!...8...|
00000280 00 00 00 00 10 00 01 00 00 64 61 74 61 5f 69 74 |.........data_it|
00000290 65 6d 73 00 73 74 61 72 74 5f 6c 6f 6f 70 00 6c |ems.start_loop.l|
000002a0 6f 6f 70 5f 65 78 69 74 00 5f 73 74 61 72 74 00 |oop_exit._start.|
000002b0 40 00 00 00 01 01 00 00 4f 00 00 00 01 01 00 00 |@.......O.......|
000002c0
现在我们来分析.section
我们自己在程序中定义了几个段-----.text和.data两个段,
我们看.data段的地址段的内容时,是这样的:
地址段是:00000060~00000098
.data段将被原封不动的加载到内存中。
那么分析.shstrtab 段和.strtab段后发现:
.shstrtab 保存的是各个section的名字
.strtab 保存的是程序中用到的符号的名字。
每个名字的哦以NULL 结束的字符串。
.rel.text 告诉连接器指令中的那些地方需要做重定位。
yskcg@yskcg workc]$ objdump -d maxnum.o
maxnum.o: file format elf32-i386
Disassembly of section .text:
00000000 <data_items>:
0: 03 00 add (%eax),%eax
2: 00 00 add %al,(%eax)
4: 43 inc %ebx
5: 00 00 add %al,(%eax)
7: 00 22 add %ah,(%edx)
9: 00 00 add %al,(%eax)
b: 00 de add %bl,%dh
d: 00 00 add %al,(%eax)
f: 00 2d 00 00 00 4b add %ch,0x4b000000
15: 00 00 add %al,(%eax)
17: 00 36 add %dh,(%esi)
19: 00 00 add %al,(%eax)
1b: 00 22 add %ah,(%edx)
1d: 00 00 add %al,(%eax)
1f: 00 2c 00 add %ch,(%eax,%eax,1)
22: 00 00 add %al,(%eax)
24: 21 00 and %eax,(%eax)
26: 00 00 add %al,(%eax)
28: 16 push %ss
29: 00 00 add %al,(%eax)
2b: 00 0b add %cl,(%ebx)
2d: 00 00 add %al,(%eax)
2f: 00 42 00 add %al,0x0(%edx)
32: 00 00 add %al,(%eax)
34: 00 00 add %al,(%eax)
...
00000038 <_start>:
38: bf 00 00 00 00 mov $0x0,%edi
3d: 8b 04 bd 00 00 00 00 mov 0x0(,%edi,4),%eax
44: 89 c3 mov %eax,%ebx
00000046 <start_loop>:
46: 83 f8 00 cmp $0x0,%eax
49: 74 10 je 5b <loop_exit>
4b: 47 inc %edi
4c: 8b 04 bd 00 00 00 00 mov 0x0(,%edi,4),%eax
53: 39 d8 cmp %ebx,%eax
55: 7e ef jle 46 <start_loop>
57: 89 c3 mov %eax,%ebx
59: eb eb jmp 46 <start_loop>
0000005b <loop_exit>:
5b: b8 01 00 00 00 mov $0x1,%eax
60: cd 80 int $0x80