【问题标题】:ASM 8086 : How is coding with multiple code segments different from coding with one code segment?ASM 8086:使用多个代码段进行编码与使用一个代码段进行编码有何不同?
【发布时间】:2017-09-25 18:11:54
【问题描述】:

我是一名高中生,今年开始学习汇编。

我目前正在制作 Pacman 克隆作为我的最终项目。
我遇到的唯一问题是我的代码很大,而 *.exe 文件几乎是 64KB。

所以我的问题是,如果我转向模型介质,我需要做什么才能使我的代码与额外的代码段一起工作?

我认为我需要使用Icall 而不是call,并更新程序,因为现在每次我调用它们时,segment 和 ip 都会被推送,但是我还需要做些什么吗?

【问题讨论】:

  • 所需的具体工作量取决于选择的汇编程序(我假设您正在为 DOS 编程)。正如您所指出的,呼叫最终需要远距离(包括retf)。我想不出其他任何事情。如果可执行文件的大小超过 640KiB(或更小),您可能需要使用 overlays
  • @MargaretBloom 所以我需要做的就是更新程序(调用、rets、堆栈中的参数地址等),就这样吗?只有当可执行文件大于 640KB 时才需要使用叠加层?
  • 自从我上次编写多个代码段以来已经有很长时间了,最​​好等待更知情的人:) 但我很想回答:是的
  • 您不需要任何接近 64K 的代码就可以在汇编中编写 Pacman 克隆。由于缓冲区、地图和位图等数据,您的 .EXE 的大小可能接近 64K。确保您使用的是小型内存模型,具有单独的代码和数据段,并让您的链接器生成链接映射以查看每个段的大小。
  • 我同意罗斯的观点。您非常不太可能需要超过 64K 字节的代码。您可能可以摆脱小型模型,其中有一个最大 64K 字节的代码段和一个最大 64K 字节的数据/堆栈段。如果这还不够,那么最有可能的选择是紧凑模型,它有 1 个代码段和多个数据段。我怀疑您是否需要具有多个代码段的中型模型。如果您有超过 64K 字节的汇编代码,则说明您过度使用宏,导致内联代码臃肿。将它们更改为过程。

标签: assembly executable x86-16


【解决方案1】:

如果您在具有多个代码段的模型中工作,则每个代码指针都会变成一个 32 位指针。这意味着:

  • 您需要使用call farret far 而不是callret(这是汇编程序可能为您做的事情)
  • call far 将一个四字节的返回地址压入栈中,因此需要调整获取参数的偏移量
  • 函数指针需要为 32 位,因为它们还需要包含代码段

出于您的目的,仅使用 small 模型可能就足够了,也就是说,一段用于代码,一段用于数据和堆栈。这样,您的可执行文件最大可以达到 128 kB。小模型与小模型非常相似,因为除非您需要从文本段读取/写入数据,否则您几乎可以忽略分段。

【讨论】:

    【解决方案2】:

    对于中等模型(多个代码段,一个数据段),代码段内的跳转会很小(16 位偏移),代码段之间的跳转会很远(32 位段:偏移)。对于仅在同一代码段中调用的函数,可以将它们声明为 near 并使用 near 调用(16 位偏移)。 Masm 6.x 的示例代码,nearfun 的调用和返回使用近调用和返回,farfun 的调用和返回使用远调用和返回。

            .286
            .model  medium
            .stack  1024
    
            .code   one                     ;code segment named "one"
    main    proc    far
            call    nearfun                 ;call near function
            call    farfun                  ;call far  function
            mov     ax,04c00h               ;exit to dos
            int     21h
    main    endp
    
    nearfun proc    near
            mov     ax,1
            ret
    nearfun endp
    
            .code   two                     ;code segment named "two"
    farfun  proc    far
            mov     ax,2
            ret
    farfun  endp
    
            end     main
    

    【讨论】:

    • 抱歉这个菜鸟问题,但是“.code text1/2”行是做什么的?它是否指定程序在哪个代码段上?
    • 是的,@乔丹。 .CODE 表示这是一个将存储代码的部分,它后面的标识符是该部分的名称。正如 rcgldr 所说,当您使用 medium 模型时,您有一个数据段 (.data) 和多个代码 (.code) 段,因此您需要一种方法来区分这些代码段。大多数汇编器允许您为它们分配您选择的标签。
    • @JordanErikson - 我将示例代码更改为使用名称 onetwo。对于汇编代码,程序员几乎可以使用任何名称。我认为 C 编译器使用像 x_text 这样的名称。
    • @rcgldr 您的代码在 emu8086 duplicate declaration of: CODE 和 GUI TURBO Forward reference needs override 中显示此错误。
    • @Doda - 如答案中所述,该代码适用于 Masm (ml.exe) 6.xx。我不知道其他汇编程序会如何做到这一点,但我的猜测是使用较旧的 Masm 5.xx 类型将 .code 等 doc 指令替换为 segmentends 指令。
    猜你喜欢
    • 2022-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多