| 站点地图 | 联系我
| www.asm32.net | 2006版 | 资料中心 | linux | asm/asm32 | C/C++ | VC++ | java | 书签 | ASP.Net书签 | 上善若水 厚德载物
 现在位置 :: 主页 >> 资料中心 >> ROOT / CODE / ASM/ASM32 /
 

asm32的精髓是什么?

来源(CSDN论坛)

From: http://topic.csdn.net/t/20030206/10/1406484.html

在现在的windows上写asm本来就是asm32了。

除非你要回到过去,一定要在DOS上写32位程序。

最简单的就是做成flat模式的,不分页,单任务。

5,6年前写过代码早就不知道扔哪去了。

只能说一下要点。

首先要定义两个段

code16   semgent   use16
code16   ends

code32   segment   use32
entry_32:
code32   ends


16位段里面做初始化。

先LGDT装载全局描述符表,接下来把CR0设置成1,用个短jmp跳转到下一条语句,然后用个long jmp跳转到code32。麻烦在于不能用符号描述code32的地址,例如在code32里面用标号entry_32定义个入口,跳转到那个标号。简单做法是把CS段的描述符的基地址定义成0,大小定义为4G,然后在程序运行时根据当前的16位情况下的段地址和entry_32计算出对应的32位偏移量。然后对CS选择子和算出的偏移量作一个长跳转,不幸的是masm,tasm都不能写出那样的汇编指令,必须用DB伪指令直接定义长跳转指令的机器码。进入32位段后就可以根据GDT中定义的其它段描述符选择子初始化其它段寄存器,然后就是你的32位程序了。

不过DOS下自己写的32位程序几乎什么都不好做,任何一个中断你都不能调用,要显示点东西只有自己去直接写屏幕了。

如果上面的简单的程序弄出来了,就可以考虑一下使用分页,关键就在于地址空间的计算,定义好两级页表后,装载CR3,给CR3的值应该是页表所在的物理地址,就是4G线性空间内的那个偏移。不能搞错了。

还想弄点简单的多任务,就该使用时钟中断了,这个时候不要忘了设置好IDT,这个东西的配置还算简单,然后就是LDT,为了简单也可以不要直接使用GDT里面的定义就好,最麻烦的是TSS,对于每个任务,原则上应该有各自的页表,每个任务都让它从0地址开始。作为实验做两个就好互相跳转。跳转还是用长跳转,和进入保护模式的那个跳转一样,必须用DB定义,段选择子就是TSS的选择子,32位偏移量无所谓,一般都填成0,因为跳转以后的EIP是从TSS里面取出来的,也就是上次离开该任务的指令的下一条指令的地址。定义TSS的时候不要忘了存储浮点状态的空间,记得FSAVE,返回以后记得FRESTORE,这两条指令后不要忘了FWAIT。

一定要调BIOS中断,要么就进V86,要么暂时切换回实模式。如果要写成V86模式的,千万小心页表定位,必须把BIOS程序所在的位置保留在原来的位置上。

这些东西玩玩就好了,没有必要在上面浪费时间,反正又不用去写操作系统,16位模式照样可以用32位寄存器,算点东西就将就了。

Link: http://www.asm32.net/article_details.aspx?id=5792


浏览次数 0 发布时间 2011/10/29 18:16:26 从属分类 ASM/ASM32 【评论】【 】【打印】【关闭
 
| www.asm32.net | 2006版 | 资料中心 | linux | asm/asm32 | C/C++ | VC++ | java | 书签 | ASP.Net书签 | 京ICP备09029108号-1