ASM 8086免费细分

时间:2015-05-19 13:22:00

标签: assembly x86-16 segment

我需要一个免费的段来保存数据,哪些段可以免费使用?

我试图将位图数据保存在内存中,位图数据的大小是64K所以我想将它保存在一个单独的段中。

(我担心我会覆盖使用的片段)

(DOS,ASM 8086,TASM它的相关性)

2 个答案:

答案 0 :(得分:0)

您可以在可执行文件中分配静态缓冲区,也可以像Micheal建议的那样动态分配缓冲区。要静态分配64K缓冲区,您需要执行以下操作:

BITMAPBUF SEGMENT PARA PRIVATE
    DB  0ffffh DUP (?)
BITMAPBUF ENDS  

BITMAPBUF2 SEGMENT BYTE PRIVATE
    DB  ?
BITMAPBUF2 ENDS

对于我正在使用的TASM和TLINK版本似乎没有正确处理64K段这一事实,BITMAPBUF2段有点骇人。所以我创建了两个链接器将彼此相邻放置的段。

要使用MS-DOS动态分配缓冲区,您需要这样的代码:

    mov ah, 48h
    mov bx, 1000h 
    int 21h
    jc  failed
    mov [bitmapbuf_seg], ax

请注意,如果您尝试创建.COM文件,则这两种方法都将失败。前者因.COM文件不能大于64K而第二个因为.COM可执行文件在启动时分配所有可用内存(*),所以没有内存可动态分配。您可以在使用INT 21h / AH = 48h之前释放未使用的内存来解决后来的问题,但更简单的解决方案是构建.EXE。

这里有一些示例代码,它将A000:0000的VGA帧缓冲区的内容复制到缓冲区。取决于缓冲区是静态还是动态分配,取消注释两行中的一行:

    ; mov   ax, BITMAPBUF
    ; mov   ax, [bitmapbuf_seg]
    mov es, ax
    xor di, di
    mov ax, 0a000h
    mov ds, ax
    xor si, si
    mov cx, 8000h
    rep movsw

(*)实际上它分配了最大的自由连续内存块,但这通常意味着几乎所有的常规内存。

答案 1 :(得分:0)

如果我们启动一个可执行文件,那么DOS会给它所有的免费ram。但我们不知道哪个部分真正免费。因此,如果我们想要分配一些ram,我们必须在我们分配一些ram之前回馈我们不需要的所有ram,以确保这些段不被使用。

          call SETFREE               ; first we have to free the rest of RAM
          mov      bx, 2000h         ; allocate 128 KB
          call GETSPACE
          jc  ERROR
          mov      [NEWSEG], ax      ; store segment address

;------------------------------------
SETFREE:  mov      bx, ss            ; calculating the amount of bytes
          mov      ax, es            ; that our program is needed
          sub      bx, ax            ; for the code, data and stacksize
          mov      ax, sp            ; and free the rest
          add      ax, 0Fh
          shr      ax, 4
          add      bx, ax
          mov      ah, 4Ah
          int    21h
          ret
;------------------------------------
GETSPACE: mov      ah, 48h
          int    21h
          ret