教育问题,如果有任何材料,请发布。
通常,lods汇编指令将DS:EDI中的字节/字/双字加载到AL / AX / EAX中。 因此,为了做到这一点,需要有一个DS指向的段。
但是,如果我只创建一个.code段,我不打算把任何东西放到DS中,我会使用lods(或lodsb / lodsw / lodsd)会怎么样?
我知道我可以使用其他寄存器,例如
lods DWORD PTR SS:[ESI]
但是,让我说我没有数据。它会尝试从受保护的内存区域获取某些内容导致崩溃/错误吗?
答案 0 :(得分:0)
段寄存器地址与程序段不同。在32位程序集中,段寄存器包含一个段选择器,它选择先前在通用/本地描述符表中定义的段。我不打算在这里详细介绍,但是使用段寄存器和描述符表进行操作是由操作系统处理的,并且分段并不像80386之前那样重要。
您在汇编源中提到的段或部分现在用于将具有类似用途的数据分类为更大的块(通常是部分)。由于这些部分具有相似的目的(它们以类似方式使用/仅在某些方面使用),因此可以将它们放入具有某些访问限制的内存中,以便代码可执行但不可写,并且数据可写但不是可执行的。
术语section
和segment
的含义在可执行文件格式中是不同的,并且在格式规范中检查它总是必要的。
CS
,DS
和ES
(+可能SS
)主要指的是包含大部分虚拟内存的相同段描述符。你不需要关心其中的内容,实际上,你也不应该这样做。您的链接器将计算代码中各部分的地址,对齐它们,然后将某些符号的每个用法替换为准确指向数据的位置。
TL; DR :您的段寄存器的内容对您没有任何意义,并且它与您在汇编源中定义的段没有任何关联。 LODxx
指令可以使用任何段寄存器(segment override prefix
使其成为可能),但ESI
寄存器必须用作源索引。
答案 1 :(得分:0)
大多数32位操作系统使用" flat"存储器布局使段寄存器CS,DS,ES,FS,GS和SS指向相同的存储区。
如果您的可执行文件具有.data段,则根本不重要。
然而,有两个问题可能很有趣:
在这两种情况下都会发生异常,这意味着会通知操作系统。在Windows中你会看到这个"一般保护错误"消息框......
在"真实模式" (8086模式)DS和SI(不是ESI)的任何值都将构成一个有效的地址,因此" lods"指令永远不会在8086模式下失败。