This blog was last modified 427 days before.
Create Your Own Inc File
If you have used some other high level programing language before, you may familiar with the conception of librarys , and you may also already know how to create the libraries in other program language. But how can you do this in ASM?
The answer may be the .inc
file. We already knew that emu8086
provides a emu8086.inc
file for us, and it is quite useful for us, but how can we create one that made by our own? What things should we put an eye on?
I think a good way learning this is learn from emu8086.inc
, check the Github - emu8086.inc, read the code, and see how this file deal with claiming macros and functions.
Actually the content below is a conclusion for the things I learnt from that tiny emu8086.inc
file.
Here
inc
meansinclude
in English, and you can see Windows marked .inc file as Include File , see picture below.
If you need to use register
No matter whether you are using: macro or procedure, there is one thing you need to remember:
If you need to use register during this deal, push them before use and pop them after your procedure finish.
add_byte_store_al macro num1, num2
push ah
push al
mov al, num1
mov ah, num2
add al, ah
pop al
pop ah
add_byte endm
Notice the order is reversed compared to push
when you pop
them.
If You Want To Use Macro Contains Label
As we said before, generally we should always using LOCAL
to mark the labels in macros.
If You Want To Define Functions
In emu8086.inc
, they wrapped the function definition into macro. Here is some of the benifits I could figured out:
- Enable adding Safe Jump mechanism.
- Only Define If You Need. Accelerate the compile speed.
- Enable Local Label For Functions.
Here as you see, if you declare two different functions which contains the labels with the same name, there will be a compile time error complaining duplicated label definition. So if we used some labels in this function, we should first use LOCAL
to define these labels as local.
So here below is the recommend template to define a function in .inc
:
define_<func_name> macro
local <put all labels you will use here>
local protect_skip
jmp protect_skip
<func_name> proc
; your func code here
ret
<func_name> endp
protect_skip:
define_<func_name> endm
What is Safe Jump mechanism (actually I named it by myself so if you want you can name it yourself lol)? That's we use a jmp
operation to skip the code of our proc
definition code. The jmp protect_skip
and protect_skip
label is the code that implement Saft Jump mechanism.
Why we need to do this? Actually if you follow the rules to use .inc
file, then its okay to ignore this work and not add this so called Safe Jump mechanism. But consider if someone call define_<some_func_name>
in their code segment, then without the jump, the code inside our proc definition could be accidentally runned and cause unexpected result.
If you can't understand what I'm talk about above, then when you finish reading this passage, you can try it yourself to use define_<some_func_name>
between your code like below:
define_subab macro
local skip
;try add/remove this line and see what will happen
subab proc
sub ax, bx
ret
subab endp
skip:
define_subab endm
mov ax, 1
mov bx, 1
add ax, bx
define_subab
ret
Just add or remove the safe jump mechanism in your define_sub
code, and see how it affect the result, and to learn how Safe Jump mechanism protect your code.
When we implement the safe jump, see the value of AX
as expected since we do add ax, bx
However when we remove the safe jump code:
We just want to define the function subab
and we don't mean to use it (if we need to use it the code should be call subab
, how to use the function we defined will be talked later), but code of this function is still executed since we accidentally put the definition between our code where IP
register will point to and we don't use Safe Jump to protect the definition part of our code. Now you may know why we need this.
Use Functions
How to use this funcion? See example below:
The INC file:
; -------------------------
define_ch_dx_4321 macro
local label, var
local protect_skip
jmp protect_skip
ch_dx_4321 proc
jmp label:
label:
mov dx, cs:[var]
ret
var dw 4321h
ch_dx_4321 endp
protect_skip:
define_ch_dx_4321 endm
; -------------------------
define_ch_dx_1234 macro
local label, var
local protect_skip
jmp protect_skip
ch_dx_1234 proc
jmp label:
label:
mov dx, cs:[var]
ret
var dw 1234h
ch_dx_1234 endp
protect_skip:
define_ch_dx_1234 endm
; -------------------------
The ASM file:
include "ahucon.inc"
code segment
start:
mov cx, cs:[var]
mov ah, 4ch
; call functions
call ch_dx_1234
call ch_dx_4321
int 21h
var dw 5678h
; use these functions in ahucon.inc
define_ch_dx_1234
define_ch_dx_4321
code ends
end start
Basically, you just need to add define_<func_name>
before end
, then just use it in your code!
Define & Use Local Function Variables
You should pay extra attention when you try to define and use a local variable in your self-defined function.
- Use
LOCAL
to mark your variable name. - Use
CS:[<var_name>]
when you need to access it.
Check the above example again how to apply these two point into your code.
No comment