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
.code

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

END
```
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:
```DEFINT A-Z
DECLARE SUB vmode

vmode
```
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
.code

PUBLIC func
func PROC
mov ax,3
retn
func ENDP

END
```
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
DECLARE FUNCTION func

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:

```DECLARE SUB vmode
```
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
retn
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:

```DEFINT A-Z
```
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
.code

mov bx,sp	;moves SP into BX.
mov ax,[bx+06]
mov dx,[bx+04]
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.