80386ASM程序设计基础(十)

InstallShield Express制作Delphi数据库安装程序 关键所在用Delphi编写的数据库程序在发布时需要同时发布BDE(Borland Database Engine),但BDE占用空间较大(不同版本大小不一,最新的Delphi5有17M多),远比一般的程序本身要大。但实际上,有些文件用不上的,所以我们可以在发布时用Delphi附带的InstallShield制作安装程序来定制BDE驱动,这样可以精简我们的数据库应用程序。实现与应用参考Bde32.H 阅读详情
主要介绍段描述符,段选择子
   在保护模式下,段是实现虚拟地址到线性地址转换的基础。在保护方下,每个段有三个参数:段基址,段界限,段属性。段基址规定了线性地址空间中段的开始地址,段基址长度为32位,所以任何一个段都可以从32位线性地址空间中的任何一个字节开始,这一点和实式方式不同,实式方式下要求段的边界必须被16整除。段界限规定段的大小,段界限用20位表示,而且段界限可以是字节或4K为单位,这个称为段的粒度。当段界限以字节为单位时,那么段的范围是1字节至1M字节;当段界限是以4K字节为单位时,那么段的范围是4K至4G。段的界限同时也是用来校验偏移地址的合法性,比如说段A的基址为00123456H,段界限为1000H,如果段界限以字节为单位,那么段的范围是00123456H-00124456H;如果段界限以4K字节为单位,那么段的范围是00123456H-00223456H。事实上,段的界限也可以用来校验偏移地址的合法性,上面的例子中界限为1000H,那么偏移地址的范围就是0-1000H,如果偏移地址不在这个范围内那就会引起异常。需要说明的是,数据段有点特殊,因为数据段的偏移范围不仅仅是由段界限来决定,还要由段的扩展方向(Extension Direction)来决定,因为要照顾到堆栈段(堆栈段是一种特殊的数据段,它是向低端地址扩展的),如果段界限为Limit,段的扩展方向为向高端地址扩展的话,那么我们可以断定它是一普通的数据段,0-Limit是有效的偏移范围,而Limit以上属于无效的偏移范围;如果段界限为Limit,段的扩展方向为向低端地址扩展的话,那么可以断定它是一堆栈段,此时0-Limit是无效的偏移范围,Limit以上则属于有效的偏移范围,正好和向高端地址扩展的普通数据段相反。除了堆栈段以外,其它的段均是自然向高端扩展。
   段基址,段界限及段属性这三个参数在保护模式下用描述符来描述,每个描述符的长度为8个字节,每个段都有一个对应的描述符。在保护模式下有三种描述符:存储段描述符,系统段描述符,门描述符。
   A.存储段描述符:存储段是指程序直接执行的代码段和数据段,存储段描述符是用来描述存储段的,也可以说是用来描述代码和数据段的,它的长度为8个字节,该描述符结构示意图:
   
    第7字节  第6字节  第5字节     第4字节  第3字节  第2字节   第1字节  第0字节
   |--------|------------------|-----------------------------|-----------------|
   |段基址的|                  |                             |                 |
   |高8位   |Segment Attributes|       段基址的低24位        | 段界限的低16位  |
   | 24~31  |   段属性,占用两 |         0~23                |      0~15       |
   |        |   个字节         |                             |                 |
   |--------|------------------|-----------------------------|-----------------|
            |                  |
            |                  |
   _________|                  |_____________________________
   | 15  14 13  12 11            8 7 6     5   3           0|
   |---|---|---|---|-------------|---|--- -|---|------------|
   | G | D |0  |AVL|段界限的高4位| P | DPL |DT |    TYPE    |
   |---|---|---|---|--- ---------|---|-----|---|------------|
  
   段基址和段界限都被安排在描述符的两个域中,主要是来看段的属性:
   a.G(第15位),这是段界限粒度,即是说段界限到底是以字节为单还是以4K字节为单位。G=0表示段界限是字节,G=1表示段界限为4K字节。
   b.D(第14位),D是一个很特殊的位,在描述可执行段,向低扩展数据段或者由SS寄存器寻址的段。在描述可执行段的描述符中,D位决定了指令使用的地址及操作数据默认的大小,D=1表示默认情况下使用32位地址及32位或8位操作数,这样的代码段称为32位代码段;D=0表示默认情况下使用16位地址及16位操作数或8位操作数,这样的代码段称为16位代码段;在向低扩展的数据段中,D=1表示段的上部界限为4G,D=0表示段的上部界限为64K;在描述由SS寄存器寻址的段中,该位决定使用隐式的堆栈访问指令使用何种堆栈指针寄存器。D=1表示使用32位堆栈指针寄存器ESP,D=0表示使用16位堆栈指针寄存器SP,隐式的堆栈访问指令指的是那些指令中没有明显对SP或ESP进行操作的指令,比如说PUSH,POP,PUSHA,POPA,PUSHAD,POPAD都属于隐式的堆栈访问指令。
   c.0(第13位),这一位恒为0,为80386以后的处理器保留的。
   d.AVL(第12位),软件可利用位,主要是为了保持和以后的处理兼容。
   e.第11位到第8位是段界限的高4位。
   f.P(第7位),存在位,P=1表示描述符对转换地址有效。P=0表示描述符对转换地址无效,如果使用该描述符将会引起异常。   
   g.DPL(Descriptor Privelege Level)描述符特权级,共2位,它规定了所述段的特权级别,用于特权检查,以决定是否能对该段进行访问。
   h.DT(Descriptor Type)描述符的类型,DT=0表示存储段描述符,DT=0表示系统段描述符和门描述符。
   i.TYPE,共4位,说明存储段的具体属性:
     TYPE0:指示描述符是否被访问,用A标记,A=0表示描述符未被访问,A=1表示描述符已被访问。
     TYPE1:根据TYPE3来确定。
     TYPE2:根据TYPE3来确定。
     TYPE3:指示描述符所描述的段是数据段还是代码段,用E标记。E=0表示是不可执行段,是数据段,对应的描述符也就是数据段描述符。E=1表示是可执行段,也就是代码段,对就的描述符也就是代码段描述符。
     如果TYPE3=0,也就是说描述符是数据段描述符,那么TYPE1指示该数据段是否可写,用W标记。W=0表示对应的数据段不可写,只读。W=1表示对应的数据段可写。TYPE2则指示数据段的扩展方向,用ED标记。ED=0表示向高端扩展,ED=1表示向低端扩展。
     如果TYPE3=1,也就是说描述符是代码段描述符,那么TYPE1指示该代码段是否可读,用符号R标记。R=0表示对应的代码段不可读,只能执行,R=1表示对应的代码可读可执行。TYPE2则指示所描述的代码段是否是一致代码段,用C表示。C=0表示代码段不是一致代码段,C=1表示是一致代码段。
     TYPE3-TYPE0这四位可以列成一个表:
     ___________________________________________________________________________________
    |0000 |只读                                                                        |
    |_____|____________________________________________________________________________|
    |0001 |只读,已访问                                                                |
    |_____|____________________________________________________________________________|
    |0010 |可读,可写                                                                  |
    |_____|____________________________________________________________________________|
    |0011 |读写,已访问                                                                |
    |_____|____________________________________________________________________________|
    |0100 |只读,向低扩展                                                              |
    |_____|____________________________________________________________________________|
    |0101 |只读,向低扩展                                                              |
    |_____|____________________________________________________________________________|
    |0110 |读/写,向低扩展                                                             |
    |_____|____________________________________________________________________________|
    |0111 |读/写,向低扩展,已访问                                                     |  
    |_____|____________________________________________________________________________|
    |1000 |只执行                                                                      |
    |_____|____________________________________________________________________________|
    |1001 |只执行,已访问                                                              |
    |_____|____________________________________________________________________________|
    |1010 |可执行,可读                                                                |
    |_____|____________________________________________________________________________|
    |1011 |可执行,可读,已访问                                                        |
    |_____|____________________________________________________________________________|
    |1100 |只执行,一致代码段                                                          |
    |_____|____________________________________________________________________________|
    |1101 |只执行,一致代码段,已访问                                                  |
    |_____|____________________________________________________________________________|
    |1110 |可执行,可读,一致代码段                                                    |
    |_____|____________________________________________________________________________|
    |1111 |可执行,可读,一致代码段,已访问                                            |
    |_____|____________________________________________________________________________|                                        
    存储段描述符的结构可以这样定义:
    DESCRIPTOR STRUCT
    Segment_LimitL16 DW 0;段界限的低16位   
    Segment_BaseL16 DW 0;段基址的低16位
    Segment_BaseM8 DB 0;段基址的中间8位
    Segment_BaseH8 DB 0;段基址的高8位
    Segment_Attributes DW 0;段属性
    DESCRIPTOR ENDS
    一个任务有多个段,每个段都有一个描述符。因此在80386下,为了方便管理这些段描述符,将描述符组成一个线性表,称之为描述符表。在80386下有三种描述符表:GDT(Global Descriptor Table),LDT(Local Descriptor Table),IDT(Interrupt Descriptor Table)。在整个系统中全局描述符表GDT和中断描述符表只有一张,局部描述符表可以由若干张。每个描述符表都形成一个特殊的16位数据段,这样的特殊数据段最多可以有8192个描述符,具体使用哪一个段描述符,由段的选择子来确定。每个任务都有自已的局部描述符表LDT,它包含自已的代码段,数据段,堆栈段,也包含该任务使用的一些门描述符。随着任务的切换,LDT也跟着切换。GDT包含每一个任务都可能或可以访问的段的描述符,通常包含描述操作系统所用的代码段,数据段以及堆栈段的描述符,也包含描述任务LDT的描述符。在任务切换时,并不切换GDT。一个任务的整个虚拟地址空间可以分为相等的两半,一半空间的描述符在全局描述符表GDT中,一半空的描述符在局部描述符表LDT中。由于全局描述符表和局部描述符表都可以包含最多为8192个描述符,而每个描述符所描述的段的最大长度为4G,因此最大的虚拟地址空间为:8192*4G*2=64TB。
   段选择子用来确定使用描述符表中的哪一个描述符。实式模式下逻辑地址由段地址*16再加上段内偏移地址;保护模式下虚拟地址空间由段选择子和段内偏移来确定,和实式模式比较,段选择子代替了段值,实际上通过段选择子就可以确定了段基址。选择子的高13位是描述符表中的索引号,用来确定描述符,因为是13位,所以说最多可以有2的13次方8192个描述符,索引号:0-8191。标记TI指示是从全局描述符中读取描述符还是从局部描述符表中读取描述符。TI=0指示是从全局描述符表中读取描述符,TI=1指示从局部描述符表读取描述符。RPL表示请求特权级,用于特权检查。假设段选择子为88H,则表示请求的特权级别是0,从全局描述表中读取描述表,描述符的索引号为11H。有一个特殊的选择子称为空选择子,它的Index=0(即高13位为0),TI=0,RPL则可以为任意值。当用空选择子对存储器进行访问,会出现异常。空选择子对应于全局描述表中的第0个描述符,因此全局描述符表中的第0个描述符总是不会被访问。如果TI=1,那么就不是空选择子,它指定的是当前局部描述符表中的第0个描述符。为了更快地从段选择子中获得段的基本信息(段基址,段界限,段属性),从80386开始为每个段寄存器在硬件上配备了段描述符高速缓冲存储器,对我们写程序的人来讲,它是不可编程的。有了这种高速缓冲寄存器后,每当将选择子装入段寄存器后,处理器将自动装入描述符表中相应的描述符,并将描述表的信息装入到高速缓冲寄存器,这样可以加快访问速度,以下是段选择子的结构示意图:
  
   15________________________________________________________________3__2__1_____0 
  |                                                                |TI |  RPL   |
   |________________________________________________________________|___|________|
 
基于Kali Linux构建DDOS攻防实验环境:从攻击模拟到防御实践 分布式拒绝服务(DDoS)攻击是网络安全领域常见的威胁形式,其原理是通过海量恶意流量耗尽目标服务器的资源,导致服务不可用。理解其攻击机制对于构建有效防御体系至关重要。在工程实践中,安全研究人员和运维工程师常借助Kali Linux等工具集进行攻击模拟与特征分析,从而验证防护策略的有效性。通过搭建隔离的虚拟化实验环境,可以安全地复现SYN Flood、UDP Flood等典型攻击场景,并结合tcpdump、Wireshark等流量分析工具,直观识别攻击特征。这种基于实验的攻防视角转换,不仅能深化对DDoS原理 阅读详情

相关推荐

【信息科学与工程学】计算机科学与自动化——第三百零五篇 数据中心 Scale-Up、Scale-Out、Scale-Across 20

GPU 训练中的各种算子融合技巧、梯度压缩与稀疏通信的高级变体、混合专家模型的负载均衡与通信优化、长序列模型的注意力机制优化、模型量化与蒸馏的联合优化、分布式训练中的容错与恢复、以及一些新兴硬件特性的建模(如 HBM3、GDDR7、CXL 3.0 内存语义、PCIe Gen6 PAM4 信令等)。每条仍然包含四个方程式子节。

weixin_49199313的博客 242

80386汇编语言问题相关

汇编语言问题相关 汇编语言问题相关 汇编语言问题相关 汇编语言问题相关 汇编语言问题相关

80386ASM程序设计基础

80386ASM程序设计基础,是转帖。 80386ASM程序设计基础,是转帖。

使用ASM为一个类增加属性

使用ASM可以方便的访问和修改一个类,或者在JVM载入前动态更新一个类也是可以的,如下, 为一个类动态增加一个属性,类Student如下: public class Student { private int age; private String name; public int getAge() { return age; } public void ...

weistar103的专栏 1300

80386asm汇编语言

80386asm 汇编的一些集合文档 可以看看

80386ASM程序设计基础()

 主要介绍系统地址寄存器和控制寄存器以及在程序中实方式下与保护方式下的切换   80386处理器新增了一组控制寄存器CR0,CR1,CR2,CR3和一组系统地址寄存器GDTR,LDTR,IDTR,TR,它们全部都是32位的。CR0包含了指定处理器工作方式的控制位,CR1保留未使用,CR2和CR3由分页管理部件使用,CR0中的5~30位和CR3中的0~11位必须为0,分别介绍如下:     ____

kingcaiyao的专栏 2536

DELPHI中SQL程序的发布方法

DELPHI中SQL程序的发布方法 提交日期:2003-10-25

创业轨迹 1242

Install Shield制作安装包技巧(注册篇)

1、IIS或PWS虚拟目录  对于B/S版本的安装,可以用Install Shield创建IIS虚拟目录(在win2000下面可以用VirtualRoot.ADSI对象,Win98下面直接写注册表)。  //win2000下设置IIS虚拟目录  prototype SetVirtualRootbyNT(STRING, STRING);  //传入路径,虚拟目录名  function SetVirt

Joetao的专栏 1538

用Delphi编写安装程序(1)

用Delphi编写安装程序(1) [ 作者: 俞文群 添加时间: 2001-5-5 18:01:08 ] 当你完成一个应用软件的开发后,那么你还需要为该软件做一个规范化的安装程序,这是程序设计的最后一步,同时也是很重要的一步,因为运行安装程序往往是用户做的第一步操作。   很多报刊文章介绍了许多如何利用installshield等工具软件来制作安装程序的方法,这种办法可以很快建立起较常见...

yesjavame 326

Delphi与Windows 7下的用户账户控制(UAC)机制(加小盾牌),注册表没反应

WIN7, Vista提供的UAC机制,它的主要目的是防止对于操作系统本身的恶意修改。对于Delphi程序的影响,UAC主要在于以下几点:1、由于UAC机制,Delphi对于系统的操作可能无声的失败,而同样的程序,在2000/X下面可能运行正常。譬如注册表的改动。。。2、为了避免这样的情况,Delphi程序必须支持Vista UAC标注,也就是说,在UAC程序的图标下面显示盾牌标志。这样...

weixin_30888707的博客 106

ado+sql server的发布

jojo的解决之道:1.准备一份Install Shield Express,最好是2.01以上的版本,在Delphi的安装盘上有一个专用版本也可以用,按照制作一般程序安装盘的方法建立安装程序,必须安装BDE和SQL LINKS.2.在你的WindowsSystem下面找到以下几个文件(当然你的机器必须已经安装SQLServer):Dbmssocn.dll TCP/IP 支持文件Dbmsspxn.

袁杨的飞 - CSDN专栏 1431

怎样制作使,用户在安装我的程序时将SQL Server2000客户端企业管理器一起安装

文档标题:怎样发布基于MS SQL Server的程序 关 键 字:发布基于MS SQL Server的程序 本文章自 2003-3-1 添加到 C++ Builder 研究 网站以来,已被阅读 1999 次。 -------------------------------------------------------------------------------- 怎样发布基于MS SQ

忧郁的海风 1848

VB6程序运行错误Run-time error 339: Tabctl32.ocx的解决办法

运行错误Run-time error 339: Tabctl32.ocx的解决办法[问题] 最近一段时间与教研室的各位老师在做一个山东省一级OFFICE模拟软件时,前面的开发工作一切顺利,却在后面的安装运行阶段出...

conglu9824的博客 2322

Meta Llama 3安全最佳实践:如何使用Llama Guard 2构建AI内容防护系统

随着AI技术的快速发展,确保大语言模型(LLM)的安全使用变得至关重要。Meta Llama 3作为最新一代开源大语言模型,不仅在性能上有所突破,更在安全防护方面提供了全面的解决方案。本文将详细介绍如何利用Llama Guard 2构建高效的AI内容防护系统,帮助开发者在享受AI便利的同时,有效降低潜在风险。 ## 为什么需要AI内容防护系统? 在AI应用日益普及的今天,内容安全已成为不可忽视

gitblog_09772的博客 720

【转】InstallShield使用——几个技术问题介绍

InstallShield使用——几个技术问题介绍 1 几个技术问题介绍 1.1 数据库设置 在安装程序中设置数据库,有两种方法:一种采用命令行附加数据库文件,一种是通过SQL Script脚本创建数据库,对于编写SQL Script过于复杂,或创建数据库时间过长时建议采用第一种方法。 1.1.1 命令行附加数据库 1. 将数据库文件(a_...

weixin_30565327的博客 164

# lec3_exercise——使用80386分析程序除0后的过程分析

前言 对于80386而言把外部中断称为"中断",内部中断为"异常"且通常在两条指令间响应中断或异常 为了分析除0后操作系统的具体操作,我打算先从分析中断与异常的具体细节开始进行分析,进而来引出除0后的相关操作 中断异常分析 中断 中断分为可屏蔽中断和非屏蔽中断。可屏蔽中断常用于响应外部事件,当标志寄存器EFLAGS中的IF标志位置1时,INTR引脚上的高电平产生中断请求,处理器将在现行指令...

skyiea_331的博客 295

80386ASM程序设计基础()

    80386 ASM程序设计基础,呵呵,这是最近一段时间我的业余爱好。本期将连续推出若干篇有关80386ASM程序设计基础,主要介绍80386ASM指令的详细用法及如何在80386实模式下,保护模式下及虚拟8086模式编程以及我会详细介绍80386下的段页管理机制,我会将80386下的指令与8086下的相同指令进行比较。在你去看罗云彬的ASM编程之前,不妨先看看我的基础篇,希望有志于从事汇

kingcaiyao的专栏 3141
上一篇: 80386ASM程序设计基础(九)
下一篇: 通过COM使用ADO
kingcaiyao
博客等级 码龄25年 23粉丝 24原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值