请问16位代码段与32位代码段有什么区别?

icbm 2006-02-28 05:36:24
最近在看李彦昌写的“保护模式教程”,教程里只是说了代码段(存储段)描述符的第6字节的第6位对是确定该描述符所描述的代码段是16位还是32位。但是具体并没有讲16位代码段和32位代码段有什么区别。

我的理解是:
16位代码段使用的通用寄存器只能是ax(ah,al,其它类似),bx,cx,dx,si,di,堆栈push,pop时使用双
字节。
定义段时使用:

seg16_name segment use16
... ...
seg16_name ends

32位代码段使用的通用寄存器可以是eax,(ax,ah,al,其它类似),ebx,ecx,edx,esi,edi,堆栈push,pop时使用四字节。

seg32_name segment use32
... ...
seg32_name ends

但我发现教程在16位代码段中,也可以使用eax。如,在向保护模式切换时,使用了eax寄存器:

mov eax, rc0
or al, 01h
mov rc0, eax

而这段代码是放在16位代码段中的。请教各位大侠:16位代码段与32位代码段有什么区别?或者哪里可以找到相关资料。谢谢。
...全文
932 11 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
sjjf 2006-03-17
  • 打赏
  • 举报
回复
先mark
大熊猫侯佩 2006-03-10
  • 打赏
  • 举报
回复
开头不是有一段说明了么?要是我没记错的话。
rockefeller8 2006-03-10
  • 打赏
  • 举报
回复
跟帖的朋友,签名送分。跟贴
LN248 2006-03-04
  • 打赏
  • 举报
回复
GGG
Leomaxking 2006-03-03
  • 打赏
  • 举报
回复
mov eax, rc0 ?rc0??应该是cr0吧
glietboys 2006-03-03
  • 打赏
  • 举报
回复
首先要明确两个概念:寄存器的位数和段的位数是两个不同的概念。
寄存器的位数这个很容易理解~段的位数却有点麻烦。
我们知道,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。
还有很多细节,这里就不多说了。
Hyigle2 2006-03-03
  • 打赏
  • 举报
回复
我最近也在看保护模式,不过感觉还没走入门,路过,学习一下先!
icbm 2006-03-01
  • 打赏
  • 举报
回复
Unfortunately, MASM often defaults to 32 bit mode whenever you select an 80386 or later processor using a directive like .386, .486, or .586 in your program.

上面这段英文论述有误。只要把 .386 放在 .model 之后,Masm可以生成 16位的段(数据段、代码段)。
icbm 2006-03-01
  • 打赏
  • 举报
回复

问题已经解决。现公开如下:

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



8.8.6 The USE16, USE32, and FLAT Options
When working with an 80386 or later processor, MASM generates different code for 16 versus 32 bit segments. When writing code to execute in real mode under DOS, you must always use 16 bit segments. Thirty-two bit segments are only applicable to programs running in protected mode. Unfortunately, MASM often defaults to 32 bit mode whenever you select an 80386 or later processor using a directive like .386, .486, or .586 in your program. If you want to use 32 bit instructions, you will have to explicitly tell MASM to use 16 bit segments. The use16, use32, and flat operands to the segment directive let you specify the segment size.

For most DOS programs, you will always want to use the use16 operand. This tells MASM that the segment is a 16 bit segment and it assembles the code accordingly. If you use one of the directives to activate the 80386 or later instruction sets, you should put use16 in all your code segments or MASM will generate bad code.

Example of use16 operand:

seg1 segment para public use16 'data'
.
.
.
seg1 ends
The use32 and flat operands tell MASM to generate code for a 32 bit segment. Since this text does not deal with protected mode programming, we will not consider these options. See the MASM Programmer's Guide for more details.

If you want to force use16 as the default in a program that allows 80386 or later instructions, there is one way to accomplish this. Place the following directive in your program before any segments:

.option segment:use16


跟帖的朋友,签名送分。
  • 打赏
  • 举报
回复
非也。
16位代码段也可以使用32-bit寄存器,主要的差别在于16-bit段最大只能有64K。
fhb13 2006-02-28
  • 打赏
  • 举报
回复
DOS下的16位汇编也是可以用EAX等32位通用寄存器的。
楼主把那本书原文帖出来看看,你贴出来的东西太少了我看不明白你要说什么。

21,497

社区成员

发帖
与我相关
我的任务
社区描述
汇编语言(Assembly Language)是任何一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。
社区管理员
  • 汇编语言
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧