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 means include in English, and you can see Windows marked .inc file as Include File , see picture below. image.png

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.

image.png

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

image.png

However when we remove the safe jump code:

image.png

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.