(第一、二章)nasm的汇编和反汇编

本文详细介绍了如何使用nasm进行汇编和反汇编操作,以`boot.asm`为例,通过nasm汇编成`boot.bin`,再用ndisasm反汇编成`disboot.asm`。讨论了`org 07c00h`的重要性,解释了在引导扇区编程中使用绝对地址的必要性,避免大量手动调整相对地址的繁琐。
摘要由CSDN通过智能技术生成

 

nasm的汇编和反汇编

步骤:

1. 汇编(boot.asm为boot.bin)

nasm boot.asm -o boot.bin

2. 反汇编(boot.bin为disboot.asm)

ndisasm -o 0x7C00 boot.bin >> disboot.asm

 

注:nasm和ndisasm工具都是nasm的组件:)

****************************************************************************

"boot.asm"文件:

	org	07c00h			; 告诉编译器程序加载到7c00处(见下面解释)
	mov	ax, cs
	mov	ds, ax
	mov	es, ax
	call	DispStr			; 调用显示字符串例程
	jmp	$			; 无限循环
DispStr:
	mov	ax, BootMessage
	mov	bp, ax			; ES:BP = 串地址
	mov	cx, 16			; CX = 串长度
	mov	ax, 01301h		; AH = 13,  AL = 01h
	mov	bx, 000ch		; 页号为0(BH = 0) 黑底红字(BL = 0Ch,高亮)
	mov	dl, 0
	int	10h			; 10h 号中断 (这是BIOS中断,功能号AH=13表示“从指定位置起显示字符
串”,详见附件)
	ret
BootMessage:		db	"Hello, OS world!"
times 	510-($-$$)	db	0	; 填充剩下的空间,使生成的二进制代码恰好为512字节
dw 	0xaa55				; 结束标志

 

为什么要org 07c00h?
       有很多人看了"自己动手写操作系统"或其第二版这本书后对这一行提出疑问.
       这个问题在书中作者的解释是:
       告诉编译器,将来我们的这段程序要被加载到07c00处执行.

       我们知道编译器本身在汇编时对指令的地址计算的是相对地址.而对于引导扇区,一切只是从无生有的
阶段,是按绝对地址执行.那么对于用相对地址编译的执行码就要换算成绝对地址.
       一般而言,"真实开始执行的引导扇区"都会固定装载到07c00处,主意这句话是说一个真正的引导扇区.
对于硬盘上,会有一个主引导扇区,然后由它来控制和其它引导扇区,比如grub控制windows,linux等.
那么这个主引导扇区会加载在0600h处,当选择其它可引导扇区时再将真正的可引导扇区加载到07c00h.
所以一般而言真正的可引导扇区都装载到07c00h处.
       因为编译器在编译时的地址是从第一行开始用0000h开始相对计算的.假如我们定义一个str: dw "zxy"
它的相对地址是0100h,如果我们mov ax str那么就是将0100h传给ax,这在编译后的执行码中是固定的.
而引导扇区是使用绝对地址执行的,指令从07c00h处开始执行,那么访问0100h绝对是错误的访问.真实
的绝对地址是07c00h+0100h,所以如果你不写org 07c00h,把mov ax str写成mov ax str+07c00h对于
传址操作是一样的目的.对于作者的那段程序可以去掉第一行的org 07c00h.把"mov ax,BootMessage"
改成"mov ax,BootMessage+07c00h",效果是一样的.
       但是如果有大量的传址操作,那就要在每个地方都要+07c00h,那是一件非常头痛的事.
       所以在第一行加上org 07c00h只是让编译器从相对地址org 07c00h处开始编译第一条指令,那么下面的
相对地址被编译加载后就正好和绝对地址吻合.

 

 

****************************************************************************

"disboot.asm"文件:

 

 

//ndisasm -o 0x7c00 boot.bin >> disboot.asm
//下面是反汇编boot.bin得到的disboot.asm文件:
//1. 程序框架
00007C00  8CC8              mov ax,cs
00007C02  8ED8              mov ds,ax
00007C04  8EC0              mov es,ax
00007C06  E80200            call word 0x7c0b
00007C09  EBFE              jmp short 0x7c09

//2. 显示字符串子例程
00007C0B  B81E7C            mov ax,0x7c1e
00007C0E  89C5              mov bp,ax
00007C10  B91000            mov cx,0x10
00007C13  B80113            mov ax,0x1301
00007C16  BB0C00    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值