3.Arm机器码
首先汇编程序转化为机器码,才能在机器内运行。
首先我们对上面的裸机的代码中生的.elf文件进行反汇编:
start.elf: file format elf32-littlearm
?
Disassembly of section .text:
?
50008000 <_start>:
.text
.global _start
_start:
????@ldr和str的操作
????mov r0,#0xff
50008000:????e3a000ff ????mov????r0, #255????; 0xff
????str r0,[r1]
50008004:????e5810000 ????str????r0, [r1]
????ldr r2,[r1]
50008008:????e5912000 ????ldr????r2, [r1]
????@程序状态字寄存器访问
????mrs r0,cpsr
5000800c:????e10f0000 ????mrs????r0, CPSR
????orr r0,#0b100
50008010:????e3800004 ????orr????r0, r0, #4????; 0x4
????msr cpsr,r0
50008014:????e129f000 ????msr????CPSR_fc, r0
????@ror:循环右移
????mov r1,#0b11
50008018:????e3a01003 ????mov????r1, #3????; 0x3
????mov r1,r1,ror#1
5000801c:????e1a010e1 ????ror????r1, r1, #1
????@lsl:左移
????mov r1,#0b11
50008020:????e3a01003 ????mov????r1, #3????; 0x3
????mov r1,r1,lsl#2
50008024:????e1a01101 ????lsl????r1, r1, #2
????@bl指令:带链接跳转
????bl func1
50008028:????eb000005 ????bl????50008044
????@b指令:
????mov r1,#6
5000802c:????e3a01006 ????mov????r1, #6????; 0x6
????mov r2,#7
50008030:????e3a02007 ????mov????r2, #7????; 0x7
????cmp r1,r2
50008034:????e1510002 ????cmp????r1, r2
????bgt branch1@gt表示大于的时候跳转
50008038:????ca000003 ????bgt????5000804c
????add r3,r1,r2
5000803c:????e0813002 ????add????r3, r1, r2
????b end
50008040:????ea000002 ????b????50008050
?
50008044
func1:
????mov r1,#23
50008044:????e3a01017 ????mov????r1, #23????; 0x17
????mov pc,lr@函数的返回,固定格式。
50008048:????e1a0f00e ????mov????pc, lr
?
5000804c
?
branch1:
????sub r3,r1,r2
5000804c:????e0413002 ????sub????r3, r1, r2
?
50008050
end:
????nop
50008050:????e1a00000 ????nop????????????(mov r0,r0)
????@tst指令:
????mov r1,#0b101
50008054:????e3a01005 ????mov????r1, #5????; 0x5
????tst r1,#0b01
50008058:????e3110001 ????tst????r1, #1????; 0x1
?
????mov r1,#0b101
5000805c:????e3a01005 ????mov????r1, #5????; 0x5
????tst r1,#0b10
50008060:????e3110002 ????tst????r1, #2????; 0x2
????@cmp指令的操作:
????mov r1,#2
50008064:????e3a01002 ????mov????r1, #2????; 0x2
????cmp r1,#1
50008068:????e3510001 ????cmp????r1, #1????; 0x1
?
????mov r1,#2
5000806c:????e3a01002 ????mov????r1, #2????; 0x2
????cmp r1,#3
50008070:????e3510003 ????cmp????r1, #3????; 0x3
?
????mov r1,#2
50008074:????e3a01002 ????mov????r1, #2????; 0x2
????cmp r1,#2
50008078:????e3510002 ????cmp????r1, #2????; 0x2
????@bic:位清除指令
????mov r1,#0b1101011
5000807c:????e3a0106b ????mov????r1, #107????; 0x6b
????bic r2,r1,#0b1000011
50008080:????e3c12043 ????bic????r2, r1, #67????; 0x43
????@and的用法:逻辑与
????mov r1,#5
50008084:????e3a01005 ????mov????r1, #5????; 0x5
????and r2,r1,#0
50008088:????e2012000 ????and????r2, r1, #0????; 0x0
?
????mov r1,#5
5000808c:????e3a01005 ????mov????r1, #5????; 0x5
????and r2,r1,#1
50008090:????e2012001 ????and????r2, r1, #1????; 0x1
????@add:加法:
????add r1,r0,r2
50008094:????e0801002 ????add????r1, r0, r2
????@sub:减法,注意被减数不能是立即数
????mov r2,#4
50008098:????e3a02004 ????mov????r2, #4????; 0x4
????sub r0,r2,#2
5000809c:????e2420002 ????sub????r0, r2, #2????; 0x2
????mov r1,#3
500080a0:????e3a01003 ????mov????r1, #3????; 0x3
????sub r3,r1,r0
500080a4:????e0413000 ????sub????r3, r1, r0
????@这是注释,mov指令
????mov r1,#6
500080a8:????e3a01006 ????mov????r1, #6????; 0x6
????mov r2,r1
500080ac:????e1a02001 ????mov????r2, r1
????mov r3,#10
500080b0:????e3a0300a ????mov????r3, #10????; 0xa
????@mvn:传值取反的值
????mvn r0,#4 @r0:4取反变为-5
500080b4:????e3e00004 ????mvn????r0, #4????; 0x4
????mvn r1,#0b111000
500080b8:????e3e01038 ????mvn????r1, #56????; 0x38
????mvn r2,r1 @r2:0b111000
500080bc:????e1e02001 ????mvn????r2, r1
Disassembly of section .ARM.attributes:
?
00000000 <.ARM.attributes>:
0:????00001741 ????andeq????r1, r0, r1, asr #14
4:????61656100 ????cmnvs????r5, r0, lsl #2
8:????01006962 ????tsteq????r0, r2, ror #18
c:????0000000d ????andeq????r0, r0, sp
10:????00543405 ????subseq????r3, r4, r5, lsl #8
14:????01080206 ????tsteq????r8, r6, lsl #4
Disassembly of section .debug_line:
?
00000000 <.debug_line>:
0:????00000060 ????andeq????r0, r0, r0, rrx
4:????001e0002 ????andseq????r0, lr, r2
8:????01020000 ????tsteq????r2, r0
c:????000d0efb ????strdeq????r0, [sp], -fp
10:????01010101 ????tsteq????r1, r1, lsl #2
14:????01000000 ????tsteq????r0, r0
18:????00010000 ????andeq????r0, r1, r0
1c:????72617473 ????rsbvc????r7, r1, #1929379840????; 0x73000000
20:????00532e74 ????subseq????r2, r3, r4, ror lr
24:????00000000 ????andeq????r0, r0, r0
28:????00020500 ????andeq????r0, r2, r0, lsl #10
2c:????16500080 ????ldrbne????r0, [r0], -r0, lsl #1
30:????2f302f2f ????svccs????0x00302f2f
34:????302f302f ????eorcc????r3, pc, pc, lsr #32
38:????2f30302f ????svccs????0x0030302f
3c:????2f2f2f2f ????svccs????0x002f2f2f
40:????30312f30 ????eorscc????r2, r1, r0, lsr pc
44:????2f302f30 ????svccs????0x00302f30
48:????2f302f30 ????svccs????0x00302f30
4c:????2f302f30 ????svccs????0x00302f30
50:????2f302f30 ????svccs????0x00302f30
54:????2f2f3030 ????svccs????0x002f3030
58:????2f2f302f ????svccs????0x002f302f
5c:????022f2f30 ????eoreq????r2, pc, #192????; 0xc0
60:????01010002 ????tsteq????r1, r2
Disassembly of section .debug_info:
?
00000000 <.debug_info>:
0:????00000045 ????andeq????r0, r0, r5, asr #32
4:????00000002 ????andeq????r0, r0, r2
8:????01040000 ????tsteq????r4, r0
c:????00000000 ????andeq????r0, r0, r0
10:????50008000 ????andpl????r8, r0, r0
14:????500080c0 ????andpl????r8, r0, r0, asr #1
18:????72617473 ????rsbvc????r7, r1, #1929379840????; 0x73000000
1c:????00532e74 ????subseq????r2, r3, r4, ror lr
20:????6d6f682f ????stclvs????8, cr6, [pc, #-188]!
24:????61732f65 ????cmnvs????r3, r5, ror #30
28:????2f61626d ????svccs????0x0061626d
2c:????6a6f756c ????bvs????1bdd5e4 <_start-0x4e42aa1c>
30:????61702f69 ????cmnvs????r0, r9, ror #30
34:????00317472 ????eorseq????r7, r1, r2, ror r4
38:????20554e47 ????subscs????r4, r5, r7, asr #28
3c:????32205341 ????eorcc????r5, r0, #67108865????; 0x4000001
40:????2e38312e ????rsfcsep????f3, f0, #0.5
44:????01003035 ????tsteq????r0, r5, lsr r0
48:????Address 0x00000048 is out of bounds.
?
Disassembly of section .debug_abbrev:
?
00000000 <.debug_abbrev>:
0:????10001101 ????andne????r1, r0, r1, lsl #2
4:????12011106 ????andne????r1, r1, #-2147483647????; 0x80000001
8:????1b080301 ????blne????200c14 <_start-0x4fe073ec>
c:????13082508 ????movwne????r2, #34056????; 0x8508
10:????00000005 ????andeq????r0, r0, r5
Disassembly of section .debug_aranges:
?
00000000 <.debug_aranges>:
0:????0000001c ????andeq????r0, r0, ip, lsl r0
4:????00000002 ????andeq????r0, r0, r2
8:????00040000 ????andeq????r0, r4, r0
c:????00000000 ????andeq????r0, r0, r0
10:????50008000 ????andpl????r8, r0, r0
14:????000000c0 ????andeq????r0, r0, r0, asr #1
????...
我们从上面的反汇编的代码看到,在内存地址的后面有一串数字,这就是机器码。
接下来我们打开我们的ARM Architecture Reference Manual.pdf。这是一份很重要的资料。在第三章的第一节:
上面就是机器码的格式了。下面是31~28四位是条件信息:
Opcode指令类型的信息:21~14位:
下面我们就以mov指令为例,来讲他的机器码的内容。就是他对应的机器码:
这里我们一下面两条代码:
为例:指令的详解
首先是反汇编:如下:
?
我们通过转变:
Mov r0,r1的机器码0xe1a00001= 0b 1110 00 0 1101 0 0000 0000 000000000001
Moveq r0,0xff的机器码0x03a000ff=0b 0000 00 1 1101 0 0000 0000 000011111111
上面就是两个指令对应的机器码:
下面是mov机器码的格式:
我们在上面的机器码分析中知道,后12位是表示数的大小的。可是只有8位2进制数大小,前面四位是移位信息位。所以表示的数最大0xff。当我们把他改为0x1ff的时候会报错:
这就是下来要学习的了:伪指令。
伪指令
2.伪指令定义:
????伪/指令本身并没有所对应的机器码,它只是在编译的时候起作用,或者转化为其他的实际指令来运行。
?
指令看似该指令执行了操作,其实他不会产生机器码。伪指令的作用:1、它只是在编译的时候起作用,就像我们在C语言用#define定义一个宏一样,只是在编译的时候起作用。
2、能够起到操作的作用,是转为其他指令运行。
一、定义类伪指令:
Global:定义一个全局的符号。
Data:定义数据段。数据存到数据段。
Ascii:字符串
Byte:字节
Word:字
Equ:相当于宏定义
Align:设置对齐。
?
代码:
?
?
?
?
编译的截图:
上图知道:data的起始地址是500080c8:往下内容:
?
上面可以看到,我们的数据已经存进了数据段了。以后,我们就可以通过标号访问数据段的数据了。
Equ:宏定义伪指令
上面可以看到r0是0x89,宏定义成功。
?
?
?
?
?
?
?
Align的例子:
我们从上面的例子知道,bh标号处的地址是500080d3,是没有四字节对齐的。现在我们设置他四字节对齐:
设置后的地址变成500080e0是能被四整除的,是四字节对齐。
Ldr的例子:
运行结果:
由于伪指令是转为实际的指令执行的呢?
反汇编看看:
他是转化为实际的ldr存储器指令运行的。
Nop的例子:是空操作是延时的作用。
反汇编:
实际的操作是mov r0,r0的操作,没有什么意义,只是延时操作。
反汇编的命令:
arm-linux-objdump -D -S start.elf
查看信息:
arm-linux-readelf -a start.elf
3.Arm机器码