Assembly 为什么可以';我不能改变段寄存器的值吗?(MASM)

Assembly 为什么可以';我不能改变段寄存器的值吗?(MASM),assembly,x86,masm,Assembly,X86,Masm,我决定自学汇编语言 我已经意识到,如果我试图更改任何段寄存器的值,我的程序将无法编译 MOV DS, 160 ;INVALID - won't assemble MOV AX, 160 ;VALID - assembles, but will probably result in an MOV DS, AX ;exception, and thus the death of your program 我发现的每一篇文章都说我确实可以更改至少4个段寄存器的值,那么给出了什么呢 我真正感兴

我决定自学汇编语言

我已经意识到,如果我试图更改任何段寄存器的值,我的程序将无法编译

MOV DS, 160 ;INVALID - won't assemble MOV AX, 160 ;VALID - assembles, but will probably result in an MOV DS, AX ;exception, and thus the death of your program 我发现的每一篇文章都说我确实可以更改至少4个段寄存器的值,那么给出了什么呢


我真正感兴趣的只是为什么在这一点上,我没有任何改变这些地址的真正目的。

你在写windows可执行文件吗

在保护模式(Win32)下,不再使用段寄存器

:

内存模型也被大大简化了 与过去不同的是 16位世界。在Win32下,我们不需要 关注记忆模型或 再也没有了!只有一个 内存模型:平面内存模型。 没有更多的64K段。这个 内存是一个很大的连续空间 4 GB。这也意味着你没有 播放段寄存器。你 可以使用任何段寄存器 寻址内存空间中的任意点。 这对程序员来说是一个很大的帮助。 这就是为什么Win32程序集 编程和C一样简单


你说你对为什么感兴趣,所以:

在实模式下,段是物理内存的64K“窗口”,这些窗口间隔16字节。在受保护模式下,段是物理内存或虚拟内存的窗口,其大小和位置由操作系统决定,并且它具有许多其他属性,包括进程访问它必须具有的权限级别

从现在起,我所说的一切都是指受保护模式

内存中有一个名为全局描述符表(GDT)的表,它保存了有关这些窗口大小、位置和其他属性的信息。每个进程也可能有本地描述符表,它们以类似的方式工作,所以我将只关注GDT

加载到段寄存器中的值称为段选择器。它是GDT或LDT的索引,带有一些额外的安全信息。当然,如果程序试图加载GDT边界之外的描述符,就会发生异常。此外,如果进程没有足够的权限访问该段,或者其他内容无效,则会发生异常

当异常发生时,内核将处理它。这种异常可能被归类为分段错误。所以操作系统会杀死你的程序

最后还有一个警告:在x86指令集中,不能将立即值加载到段寄存器中。必须使用中间寄存器或内存操作数,或弹出段寄存器

MOV DS, 160 ;INVALID - won't assemble MOV AX, 160 ;VALID - assembles, but will probably result in an MOV DS, AX ;exception, and thus the death of your program MOV-DS,160;无效-无法组装 MOV AX,160;VALID-汇编,但可能会导致 MOV-DS,AX;异常,从而导致程序的死亡 我认为应该指出的是,该体系结构允许成堆的段。但是,就主流x86操作系统而言,段寄存器仅用于几个目的:

  • 安全机制,例如防止用户空间进程彼此或操作系统受到损害
  • 处理多核/多核处理器
  • 线程本地存储:作为一种优化,一些操作系统(包括Linux和Windows)对线程本地存储(TLS)使用段寄存器。由于线程共享相同的地址空间,因此如果不使用系统调用或浪费寄存器,线程很难“知道”其TLS区域的位置。。。但是,由于段寄存器实际上是无用的,为了快速TLS而“浪费”它们并没有害处。请注意,设置时,操作系统可能会跳过段寄存器并直接写入描述符缓存寄存器,描述符缓存寄存器是“隐藏”寄存器,用于缓存由段寄存器引用触发的GDT/LDT查找,在这种情况下,如果尝试从段寄存器读取,则不会看到它
除了TLS的每个线程一个段之外,实际上只有少数段(处理器数量的倍)被使用,并且只有操作系统使用。应用程序可以完全忽略段寄存器


这是由于操作系统设计,而不是任何技术限制。可能有嵌入式操作系统需要用户空间程序来处理段寄存器,但我不知道有任何嵌入式操作系统。

这是完全错误的。几个段寄存器用于线程本地存储和异常处理。I(显然?)的意思是“由用户空间程序用于其原始目的”。OP引用的文档已过期。是否确实无法在x86上加载具有立即数值的段寄存器?我正在阅读《英特尔体系结构软件开发人员手册》(325462,合并卷),在第1002页,它讲述了一条操作码为0x8E的MOV指令,它显然将
r/m16
移动到段寄存器中。在操作系统下,还是独立?16实模式还是32位保护模式?什么代码没有编译?具有可观察效果的最小16位示例:@CiroSantilli六四事件法轮功纳米比亚威视: 我在这里追求的是概念,而不是代码示例。还有,这是七年前的事了。@EdS.日期并不重要,我每天都从老问题中学习,也回答了不少问题:-)但如果你忘记了细节,我理解。@CiroSantilli六四事件法轮功纳米比亚威视: 嗯,这是真的