Ⅰ.汇编模块化编程
0x00 一个简单的例子
我们了解模块化编程前先给出一个例子,方便大家快速了解。
SECTION MBR vstart=0x7c00 ; 起始地址编译在0x7c00mov ax,cs mov ds,ax mov es,axmov ss,axmov fs,axmov sp,0x7c00 ; 上面这些都没什么用,但是都是必须的; 就把这些理解为初始化吧 call mainjmp $eax_plus_1s:inc eaxretebx_plus_1s:inc ebxretmain:mov eax, 0mov ebx, 0call eax_plus_1scall eax_plus_1scall ebx_plus_1sadd eax, ebxrettimes 510 - ($ - $$) db 0
db 0x55,0xaa
这段代码用到了了我们今天要学的所有知识。
我们用bochs运行一下。
什么?这次几天,你就忘了?
算了,重新发一下命令。
nasm -o a.bin a.S
dd if=a.bin of=hd60M.img bs=512 count=1 conv=notrunc
bochsdbg -f bochsrc
输入c运行等一会后,再输入r命令查看寄存器数据。
得到结果3。
这段代码实际上看意思应该就大概知道了。
0x01 代码段
首先我们讲讲代码段,也就是上面代码中的。
main:...
格式如下:
代码段名:代码段
或者
代码段名称: 代码
代码段中的本质到底是什么呢?
我们可以大胆猜测一下,有如下可能:
- 类似c语言中的函数
- 类似c语言中的标签
我们可以把这个存入ax看一下试试。
SECTION MBR vstart=0x7c00 ; 起始地址编译在0x7c00mov ax,cs mov ds,ax mov es,axmov ss,axmov fs,axmov sp,0x7c00 ; 上面这些都没什么用,但是都是必须的; 就把这些理解为初始化吧 mov ax, mainjmp $times 510 - ($ - $$) db 0 db 0x55,0xaa
运行试试。
7c18应该就是一个地址,那就和c语言的标签类似。
call指令就是调用代码段,和函数调用差不多。
jmp就和c语言的goto差不多。
里面的
jmp $
就是原地循环,$就是当前指令的地址。
ret指令和return差不多。
Ⅱ.call和ret调用指令
0x00 call指令语法
call指令语法很简单:
call 标号
功能如下:
call指令可以实现调用一个子程序,在子程序里使用ret指令结束子程序的执行并返回主程序(类比C语言中的main函数调用cube函数进行理解),主程序继续往下执行。
0x01 call指令本质
call指令是一个流程转移指令,就是让程序执行的顺序发生短暂的改变,去执行别处地址上的指令,遇到ret指令后再回到原来的地方继续往下顺序执行,本质和jmp大同小异,区别是在jmp基础上增加了程序回到原来跳转处的功能。
执行的指令如下:
- 第一步:将当前的ip或者cs和ip压入栈中。即跳转前保存call指令的下一条指令的首地址
- 第二步:转移到标号处执行子程序。即修改ip或者cs和ip里的内容
例子?懒得写了
Ⅲ.jmp跳转指令
0x00 什么是jmp指令
接下来就是jmp指令了!
感觉今天这篇怪水的...
cpu要执行指令之前必须先取指(把指令从内存传输到cpu中),从而必须要给出指令所在内存单元的物理地址,寄存器cs:ip就是这个物理地址所对应的段地址和偏移地址(段地址16+偏移地址=物理地址*),而jmp指令就是用来修改ip或者cs和ip的内容,使cpu执行jmp所指向的那条指令(发生跳转/转移),不会执行原定顺序的下一条指令。所以jmp指令要给出两个信息,如下:
jmp指令要给出两种信息:
- 转移的目的地址
- 转移的距离/偏移地址(距离不同转移的类型不同)
- 段间转移(远转移):同时修改cs和ip
- 段内短转移:jmp short 标号 ;只修改ip的值,ip的修改范围为-128~127(负数跳转方向是jmp指令之前,否则是之后),8位的位移
- 段内近转移:jmp near ptr 标号 ;只修改ip的值,ip的修改范围为-32768~32767,16位的位移
0x01 jmp指令格式
备注:在源程序中,不能直接使用“jmp 2000:0100"这样的转移指令来实现段间转移,这种方式在debug模式中使用的汇编指令,在源程序中写,编译器并不识别(编译报错)
懒得写了,截的别人的图。
例子?懒得写了
我们这个都是按照上面图片讲的,例子都没有。
Ⅳ.inc自加指令
这个指令应该是我们这节课最简单的一个指令了。
0x00 inc指令是什么
inc指令差不多相当于c语言中的++一样,不过没有先后一说。
也就是
inc ax
相当于汇编中的
add ax, 1
这也太tm简单了,我就不再讲了。
总结:
这节课主要讲的就是汇编模块化编程,还有一个自加指令。
还是很简单的。最后建议大家还是自己多试试,不要只看:
纸上得来终觉浅,绝知此事要躬行。