CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
不看会后悔的Windows XP之经验谈 简单快捷DIY实用家庭影院
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  其他开发语言 >  汇编语言

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

楼主icbm(雪狼)2006-02-28 17: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位代码段有什么区别?或者哪里可以找到相关资料。谢谢。  
  问题点数:100、回复次数:11Top

1 楼fhb13(游途道标)回复于 2006-02-28 17:53:26 得分 15

DOS下的16位汇编也是可以用EAX等32位通用寄存器的。  
  楼主把那本书原文帖出来看看,你贴出来的东西太少了我看不明白你要说什么。Top

2 楼DelphiGuy()回复于 2006-02-28 23:26:38 得分 15

非也。  
  16位代码段也可以使用32-bit寄存器,主要的差别在于16-bit段最大只能有64K。  
  Top

3 楼icbm(雪狼)回复于 2006-03-01 15:28:32 得分 0

 
  问题已经解决。现公开如下:  
   
  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  
   
   
  跟帖的朋友,签名送分。  
  Top

4 楼icbm(雪狼)回复于 2006-03-01 15:36:04 得分 0

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位的段(数据段、代码段)。  
  Top

5 楼Leomaxking(害怕孤独,但已习惯孤独)回复于 2006-03-03 11:37:00 得分 15

mov   eax,   rc0   ?rc0??应该是cr0吧Top

6 楼hyigle_love(parker)回复于 2006-03-03 13:34:38 得分 10

我最近也在看保护模式,不过感觉还没走入门,路过,学习一下先!Top

7 楼glietboys(大大(beer))回复于 2006-03-03 20:27:23 得分 20

首先要明确两个概念:寄存器的位数和段的位数是两个不同的概念。  
  寄存器的位数这个很容易理解~段的位数却有点麻烦。  
  我们知道,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。  
  还有很多细节,这里就不多说了。Top

8 楼LN248()回复于 2006-03-04 01:14:40 得分 5

GGGTop

9 楼rockefeller8(洛克菲勒)回复于 2006-03-10 16:13:15 得分 10

跟帖的朋友,签名送分。跟贴Top

10 楼mydo(侯佩|hopy|ks)回复于 2006-03-10 17:33:20 得分 10

开头不是有一段说明了么?要是我没记错的话。Top

11 楼sjjf(水晶剑锋)回复于 2006-03-17 21:04:49 得分 0

先markTop

相关问题

  • 这两段代码有什么区别?
  • 看看这2段 JavaScript 代码有什么区别?
  • 两段代码到底有什么区别(在线等)
  • 下面这两段代码的区别?
  • 这两段代码有何区别
  • “编译为 P-代码”和“编译为本机代码”有什么区别啊?
  • 下面的代码,有什么区别。关于滚动条的。
  • 这两行代码究竟有什么区别
  • 这两行列表代码有什么区别呀?
  • Com被编译后可代码与C++被编译后的代码有什么区别??

关键词

  • 代码
  • 位数
  • 指令
  • 汇编
  • 教程
  • 数据
  • 指示
  • 模式
  • 寄存器
  • 代码段

得分解答快速导航

  • 帖主:icbm
  • fhb13
  • DelphiGuy
  • Leomaxking
  • hyigle_love
  • glietboys
  • LN248
  • rockefeller8
  • mydo

相关链接

  • CSDN Blog
  • 技术文档
  • 代码下载
  • 第二书店
  • 读书频道

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo