In some assembly programs it is not necessary to use the ORG
directive.
Is there any situation where we must use ORG
in our program?
Where would I need to write ORG 100H
?
Note: This answer is specific to the usage of ORG
in MASM and compatible assemblers. The behaviour explained in this answer doesn't sound very smart in hindsight, so later assemblers like NASM handle repositioning inside the output chunk in a different way.
The ORG
directive serves two different purposes. It can relocate the "current output address" within the currently generated output, for example:
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 ?
to overlay the variables var1
and var2
over init_code
. As init_code
will no longer be needed after the DOS version has been checked, that memory can later be reclaimed for different purposes.
You can also use ORG
to assist with self-modifying code, like this:
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 "378h"
LPT_BASE DW ?
OUT DX, AL
These invocations of ORG
can be rewritten in different ways.
Another purpose of ORG
is to tell the linker the target offset for the part of a segment in the output file. If there is no ORG
directive, the linker just lets the first chunk for a named segment start at offset 0, and each later chunk starts at the end of the previous chunk. Let's say you have two source files assembled separately and then linked together:
DATA SEGMENT
my_data db 180h DUP 0
DATA ENDS
END
and
DATA SEGMENT
my_data2 db 80h DUP 0FFh
DATA ENDS
END
The linker will put my_data
at offset 0 into the data segment, and my_data2
at offset 180h, so the total data segment size will be 200h.
Now we could put an ORG
directive into the first assembly file, making it look like:
DATA SEGMENT
ORG 100h
my_data db 180h DUP 0
DATA ENDS
END
Now, the linker will assign the offset 100h to my_data
, and allocate the space between offset 100h and 280h to my_data
. my_data2
will be allocated at 280h. The total data segment size is still 200h, but it uses offsets 100h to 300h, instead of 0 to 200h.
On the other hand, if you use the original first file, and add an ORG 100h
directive to the second file, my_data
will be allocated at 0, and my_data2
will be forced to be allocated at 100h, overlapping the last 80h bytes of my_data
.
This use of the ORG
directive, telling the linker to force placement of segment chunks is not achievable by other means.
The most common use of ORG
is the ORG 100h
you cite in your question. You use that directive to tell the assembler/linker system, that the contents of this file are to be loaded at offset 100h in the runtime segment. This is how COM programs in DOS are set up: The first 256 bytes contain management data for the operating system and the command line (which can be re-used as 128-byte data transfer buffer), and the program code starts after it. So ORG 100h
forces the toolchain to build a program that fits the memory layout of COM programs.