I was wondering if this kind of thing is considered good practice or if its real bad I wanna simulate subroutine calls by using macros to define the inputs but use a proceedure to do all the horse work the advantage being that only a small portion of code is assembled at the point of calling the macro also functionality of macros is improved you can loop in a proceedure but not in macros.
The disadvantage is that it becomes necessary to use the org directive prior to include directives and I am not sure if it works in multiple segment exes. Also proceedures will make their way into code even if the macro which uses that proceedure is not called in the program. Also com files require that a jump be placed before the include directive or else those proceedures will be executed (not good when cpu comes accross a ret instruction)
This example demonstrates the idea what it does is prints a zero terminated string to the screen at the specified co-ordinates then returns the length of the string. both macros share the same proceedure that calculates the length of the string so thats one bonus
name "consoleio.inc"
org 100h
jmp start
$col db 0Fh
;#######################################################
; prints string to screen at the given co-ordinates
; current text colour is used (set colour with col$)
text macro x$,y$,$
push es ; preserve es
pusha ; preserve registers
mov bx,x$ ; get x value
mov dx,y$ ; get y value
lea si,$ ; get string offset
call textproc
popa ; restore registers
pop es ; restore es
text endm
textproc proc
; find length of string
mov di,si ; string address
call lenproc
mov di,si ; string address
; prepare offset for co-ordinates
push 0B800h ; screen text buffer
pop es
mov ax,160 ; screen width in bytes (80 words/chars)
mul dx ; convert to offset
add ax,bx ; x co-ordinate
add ax,bx ; double x (for word)
mov di,ax ; load finished offset
; print it to screen
mov ah,$col ; colour attributes
textloop:
lodsb ; load next char
stosw ; store char & colour
loop textloop
ret
textproc endp
;#######################################################
; returns the length of strint (terminated by zero)
; result is stored in cx
len$ macro $
push di
lea di,$ ; string offset
call lenproc
pop di
len$ endm
lenproc proc
push es ; preserve es
pusha ; preserve registers
cld ; clear flags
xor al,al ; compare zero
mov cx,-1 ; compare maximum 0FFFFh times
repnz scasb ; compare until both are zero
not cx ; invert cx
dec cx ; point cx to char before the zero
mov es,cx ; conserve value in es
popa ; restore registers
mov cx,es ; restore value
pop es ; restore es
ret
lenproc endp
start:
mov ax,03h ; text mode
int 10h ; bios call
mov ah,01h ; cursor attributes
mov cx,2B0Bh ; hide blinking
int 10h ; bios call
text 5,5,string ; prints string to screen
len$ string ; length of input is stored to cx
xor ah,ah ; wait for keypress
int 16h
ret
string db "Hello world",00h