【发布时间】:2018-04-25 10:42:54
【问题描述】:
我是 8086 汇编语言的初学者。我可以理解程序中使用的逻辑并自己编写小程序。但我只想知道这是做什么的:
.model small
.stack 300h
.model small 的解释是什么?
我正在使用masm。
【问题讨论】:
我是 8086 汇编语言的初学者。我可以理解程序中使用的逻辑并自己编写小程序。但我只想知道这是做什么的:
.model small
.stack 300h
.model small 的解释是什么?
我正在使用masm。
【问题讨论】:
使用.model tiny,您会得到一个程序,其中CS、DS 和SS 都指向相同的64KB 内存。堆栈被放置在这个 64KB 段的最高区域。
使用.model small,您将获得一个程序,其中CS 指向它自己的段,然后是DS 和SS 指向的段。堆栈被放置在SS 段的最高区域。
指令.stack 300h 告诉 MASM 堆栈的大小,因此当程序的其余部分(数据、bss、堆)与堆栈发生冲突时,MASM 可以警告您。
在这两个模型中,所有对数据项的访问都是使用近指针完成的。
【讨论】:
.model small 指令带有 模型选项。其中之一是您可以选择NEARSTACK 或FARSTACK。 NEARSTACK 的默认选择将堆栈段与数据一起分组到单个物理段 (DGROUP) 中。 假设SS等于DS。另一个选择FARSTACK,您必须明确地做出,不会将堆栈与 DGROUP 分组;因此 SS 不等于 DS。
由于 8086 是 16 位架构,因此难以访问超过 64 KB 的内存。
使用指针最有效的方法是使用专用的 16 位寄存器(如 bx)。但是,当您的程序想要访问超过 64 KB 时,它还必须使用段寄存器(如 es)。为了允许两种寻址方式,发明了memory models。
因此,.model small 指令告诉汇编器您打算使用小内存模型——一个代码段、一个数据段和一个堆栈段——并且段寄存器的值永远不会改变。
具有以下作用:
您可以将指令retn(从near 子程序返回)编写为ret。因为汇编器知道你的所有代码都在同一个段中,所以你所有的子程序都是near(即有一个16位地址),所有ret指令都意味着retn。
听起来很愚蠢和微不足道?继续阅读。
如果您的代码分散在多个源文件中,您将有call 指令调用汇编程序不知道的子例程。当你使用小内存模型时,它至少知道每个子程序都有一个 16 位的地址,并且可以使用 near 调用操作码。
您可以在不声明内存模型的情况下编写代码,但您必须使用call near 而不仅仅是call。
如果您的所有源文件都声明.model small,链接器将获取所有代码段并尝试将它们全部放入 64 KB(数据段也是如此)。如果东西太大,这可能会失败。
小型汇编程序通常不关心内存模型 - 64 KB 的代码足以编写复杂的程序,除非您使用的是大型外部库。在这种情况下,.model small 可以表示“我不关心那个内存模型的东西,只使用默认值”。
【讨论】:
small 与tiny 混淆了。 Small 可以有一个独立于 DS 的 CS。所以它可以寻址 64kb 的代码和 64kb 的数据(它们可以是同一个段,但不是必须的)。 tiny 将所有内容限制为 64kb,默认情况下,当控制权转移到 COM 程序时,CS=DS=ES=SS = PSP 段。