objdump–显示二进制文件信息,可以把程序中的机器指令反汇编。进行反汇编时需加-d选项
例如有下面一段汇编程序,求一数组的最大值的汇编程序:
#PURPOSE: This program finds the maximum number of a
# set of data items.
#
#VARIABLES: The registers have the following uses:
#
# %edi - Holds the index of the data item being examined
# %ebx - Largest data item found
# %eax - Current data item
#
# The following memory locations are used:
#
# data_items - contains the item data. A 0 is used
# to terminate the data
#
.section .data
data_items: #These are the 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 item, %eax is
# the biggest
start_loop: # start loop
cmpl $0, %eax # check to see if we've hit the end
je loop_exit
incl %edi # load next value
movl data_items(,%edi,4), %eax
cmpl %ebx, %eax # compare values
jle start_loop # jump to loop beginning if the new
# one isn't bigger
movl %eax, %ebx # move the value as the largest
jmp start_loop # jump to loop beginning
loop_exit:
# %ebx is the status code for the _exit system call
# and it already has the maximum number
movl $1, %eax #1 is the _exit() syscall
int $0x80
编译生成.o文件:
$as max.s -o max.o
用objdump工具反汇编:
$objdump -d max.o max.o: file format elf32-i386
Disassembly of section .text:
00000000 < _start >:
0:  bf 00 00 00 00       mov $0x0,%edi
5:  8b 04 bd 00 00 00 00 mov 0x0(,%edi,4),%eax
c:  89 c3                mov %eax,%ebx
0000000e < start_loop >:
e:  83 f8 00             cmp $0x0,%eax
11: 74 10                je  23 < loop_exit >
13: 47                   inc %edi
14: 8b 04 bd 00 00 00 00 mov 0x0(,%edi,4),%eax
1b: 39 d8                cmp %ebx,%eax
1d: 7e ef                jle e < start_loop >
1f: 89 c3                mov %eax,%ebx
21: eb eb                jmp e < start_loop >
00000023 < loop_exit >:
23: b8 01 00 00 00       mov $0x1,%eax
28: cd 80                int $0x80
左边是机器指令的字节,右边是反汇编结果。显然,所有的符号都被替换成地址了,比如je 23, 注意没有加$的数表示内存地址,而不表示立即数。这条指令后面的< loop_exit >并不是指令的 一部分,而是反汇编器从.symtab和.strtab中查到的符号名称,写在后面是为了有更好的可读性。 目前所有指令中用到的符号地址都是相对地址,下一步链接器要修改这些指令,把其中的地址都改成 加载时的内存地址,这些指令才能正确执行。