嵌入式linux c 学习笔记6-指令

.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

你可能感兴趣的:(c,linux,汇编,header,嵌入式,processing)