ASM 8086:多个代码段的编码与一个代码段的编码有何不同?

时间:2017-04-27 19:28:22

标签: assembly executable x86-16

我是一名高中生,今年我开始学习集会。

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

所以我的问题是,如果我转向模型媒体,我需要做些什么来使我的代码与额外的代码段一起工作?

我认为我需要使用Icall而不是call,并且从现在开始更新程序每次我将它们称为段并且ip被推送,但是还有什么我是需要做什么?

2 个答案:

答案 0 :(得分:3)

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

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

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

答案 1 :(得分:1)

对于中型(多个代码段,一个数据段),代码段内的跳转将很小(16位偏移),代码段之间的跳转将是远的(32位段:偏移)。对于仅在同一代码段内调用的函数,可以将它们声明为near,并使用near调用(16位偏移)。 Masm 6.x的示例代码, nearfun 的调用和返回使用near call和return, 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