init_code:
PUSH CS ; tiny memory model, even in EXE file
POP DS
MOV AH,30h
INT 21h ; get dos version
CMP AL, 3
JAE DOS_new_enough
MOV DX, offset error
MOV AH, 9
INT 21h
error db "Needs DOS 3.0 or newer", 13, 10, '$'
new_enough:
; some program code
ORG init_code
var1 dw ?
var2 dw ?
MOV [WORD PTR CS:LPT_BASE], 278h ; LPT2
...
MOV AL, [some_data]
MOV DX, 378h
ORG $-2 ; 2 bytes backwards, so the address of the value "220h"
LPT_BASE DW ?
OUT DX, AL
1条答案
按热度按时间dced5bon1#
ORG
指令有两个不同的用途。它可以在当前生成的输出中重新定位“当前输出地址”,例如:将变量
var1
和var2
覆盖在init_code
上。由于在检查DOS版本后将不再需要init_code
,因此该内存稍后可以回收用于不同的目的。您也可以使用ORG来帮助自修改代码,如下所示:
这些对ORG的调用可以用不同的方式重写。
ORG的另一个目的是告诉链接器输出文件中一个段的目标偏移量。如果没有
ORG
指令,链接器只让一个命名段的第一个块从偏移量0开始,后面的每个块从前面的块的末尾开始。假设你有两个单独组装的源文件,然后链接在一起:和
链接器会将偏移量为0的
my_data
放入数据段,并将偏移量为180 h的my_data2
放入数据段,因此总数据段大小为200 h。现在我们可以将一个ORG指令放入第一个汇编文件中,使其看起来像
现在,链接器将偏移量100 h分配给my_data,并将偏移量
100h
和280h
之间的空间分配给my_data。my_data2
将在280h
处分配。总数据段大小仍然是200 h,但它使用偏移量100 h到300 h,而不是0到200 h另一方面,如果使用原始的第一个文件,并向第二个文件添加
ORG 100h
指令,则my_data
将分配在0,而my_data2
将强制分配在100 h,与my_data
的最后80 h字节重叠。使用
ORG
指令,告诉链接器强制放置段块,这是其他方法无法实现的。ORG
最常见的用法是您在问题中引用的ORG 100h
。您使用该指令告诉汇编器/链接器系统,该文件的内容将在运行时段的偏移量100 h处加载。这是DOS中COM程序的设置方式:前256个字节包含操作系统和命令行的管理数据(可以重用为128字节的数据传输缓冲区),程序代码在它之后开始。因此org 100h
强制工具链构建适合COM程序内存布局的程序。