16位代码段与32位代码段的区别

16位代码段与32位代码段的区别:
16位代码段与32位代码段的区别如下:
16位代码段最长只能为64k,段内偏移量为16位,默认的指令地址及操作地址为16位;
 32位代码段最长可以4G,段内偏移量为32位,默认的指令地址及操作地址为32位。
是否能够使用   eax,   edx   等寄存器与是否使用16位代码段及32位代码段无关。16位代码段、32位代码段都可以使用   eax,   edx   等寄存器。
如果要使用   eax,   edx   等32位寄存器,必须在代码中指定   .386,   .386p,   .486,   .486p   等指示符。
在DOS实模式下,只能使用16位代码段。
在MASM中,如果把   .386,   .386p,   .486,   .486p   等指示符放在   .model   之前,那么所有的段(数据段、代码段)默认为32位; 如果把   .386,   .386p,   .486,   .486p   等指示符放在   .model   之后,那么所有的段(数据段、代码段)默认为16位。

可以在定义段时,用   USE16   或   USE32   明确指定是使用16位的段(数据段、代码段)还是32位的段(数据段、代码段)。

部分参考资料:

http://www.arl.wustl.edu/~lockwood/class/cs306/books/artofasm/Chapter_8/CH08-3.html#HEADING3-42
首先要明确两个概念:寄存器的位数和段的位数是两个不同的概念。
寄存器的位数这个很容易理解~段的位数却有点麻烦。
我们知道,8086的CPU的寄存器是16位的,80386以上的CPU是32位的;这在汇编语言中的体现就是.386p等伪指令。
如果你使用了.386p伪指令,那么汇编的编译程序才会将你的指令编译为80386认识的机器指令,汇编语言默认的是使用.8086伪指令,很明显,这个时候汇编编译程序只是将你的汇编程序编译为8086认识的机器语言,这个时候当然也不可以用EAX等寄存器了,不然编译程序会出现错误提示。如果你要使用EAX等寄存器,就要这个之前加上.386或者之上的伪指令。
简单的来说,寄存器的位数是.386等伪指令决定的,和其他无关。
而段的位数却是由段定义说明中的use16和use32这两个中的其中一个决定的。其实,汇编编译程序在将USE16或者USE16编译成机器语言的时候,就是段描述符中的第6个字节的第6位(我们一般称为D位),如果是USE16,就将该为设为0,如果是USE32,就设置为1
16位的代码段和32位的代码段很明显的一个区别就是段大小的限制:一个是64k,一个是4G。细节上却有很多差别,比如对于一个Push   10h这样一个指令,如果段是16位的,sp=sp-2,如果段是32位
的,就是sp=sp-4,当然,如果如果你是PUSH   EAX的话,无论段是16位还是32位,都是SP=SP-4。
还有很多细节,这里就不多说了。
发布了149 篇原创文章 · 获赞 22 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/deniece1/article/details/103321048