QB Times Issue #9

ASM part 6 by abionnnn

"learn asm in 1 hour flat"

Lesson no.9 Putting it together

Now that you are equiped with the knowledge to make some routines, lets get started on some real programming =P
.model medium,basic
.stack 100h

PUBLIC vmode
vmode PROC
	mov ax,13h
	int 10h
vmode ENDP

What the above code did was make a routine called vmode which switched to mode 13h. Compile it and Link it as a QuickLibrary and load it up in QuickBASIC. Enter this code:

Running this code will call the asm routine that we defined before and switches the video mode to mode 13h (320x200x256). This is an example of a subroutine that is similar to one made in QB. Lets say we no longer want it simply to be called, but we want it to actually return a value. (i.e behave like a function) The below code shows how to do so:
.model medium,basic
.stack 100h

func PROC
 mov ax,3
func ENDP

Now, the way QB retreives a returned value is via the AX register. Placing 3 in the AX register and returing to QB will return the value 3 if the above routine is defined as a function that returns an INTEGER:
DEFINT A-Z		'defines all names from A to Z as Integers

PRINT func
The above code would simply display the number 3. But now, this is rather boring really. These routines have to give you the same stuff time and time again ... or do they? =D

Now whenever you pass a variable to a function in QB it is placed on top of the stack. That pushes down the return segment and offset that is given to the routine. Lets look at the stack layout of a function we made before:

Offset Value 02 BASIC segment 00 BASIC offset <== Stack Pointer (SP)

Every time a function is called, the segment is pushed and then the offset. This is so the code knows where to go back once control has been regianed to QB. Lets say we modified vmode to become like so:

vmode PROC
 push ax
 mov ax,13h		<== lets say we are at this command.
 int 10h
 pop ax 
vmode ENDP
If we are on the second line, the stack would look so this:

Offset Value 04 BASIC segment 02 BASIC offset 00 AX <== Stack Pointer (SP)

This is very important to realise because if not kept in mind, you might access values you don't want.

Lesson no.10 Extended mov commands

There are many many many many combinations that the mov command can take in its operators. We know that square [brackets] around an register/immedate value causes the CPU to access what is at it's offset. Funnily enough, you can also access what 2 (or any number in a matter of fact) bytes in front of a register by doing this:
mov ax,[bx+02]
This can only be done with BX,BP,SI and DI which are all pointer registers.

Lets say we make a hypothetical function addone. In QB, this is how we define addone:

This means that after calling addone the stack will look like this:

Offset Value 04 x 02 BASIC segment 00 BASIC offset

The arguments are always placed before the BASIC segment and offset. so if theres a hypothetical function xaddbyy(BYVAL x,BYVAL y)

The stack would be:

Offset Value 06 x 04 y 02 BASIC segment 00 BASIC offset <== Stack pointer (SP)

The arguments are added ontop of each other (remeber the stack starts from the bottom upwards). Let us code this xaddbyy function:

.model medium,basic
.stack 100h

PUBLIC xaddbyy
xaddbyy PROC
	mov bx,sp	;moves SP into BX.
	mov ax,[bx+06]
	mov dx,[bx+04]
	add ax,dx
	retn 4		;return 4??? what does that mean? well, put simply QB pushes 2 integers
			;(x and y which are 16-bit thus 2*2=4 bytes) and leaves the routine to
			;handel the rest. When you go back to QB it does not bother removing what
			;you have'nt used. This would return the x and y and free up the stack.
			;Thus if you had a routine xaddyaddz (x,y,z) then you would retn 6.
xaddbyy ENDP

This would return x+y in ax. It's very simple really, and once you get the concept the applications start following in. Next issue, we are looking at some of these applications and how to apply it to your programs! That's all for now, see you next time!

This article was written by abionnnn (abionnnn@geocities.com).

Copyright 2000, Marinus Israel & Jorden Chamid