'=========================================================================== ' Subject: ASSEMBLY IN QBASIC 2: DATASEG Date: 12-01-96 (05:37) ' Author: Rick Elbers Code: QB, QBasic, PDS ' Origin: t030611@tip.nl Packet: ASMCODE.ABC '=========================================================================== 'ASSEMBLY IN QBASIC PART 2: USING DATASEGMENTS '---------------------------------------------- 'Rick Elbers november 1996 'This short article is ment as a follow up on STEPHAN van Loendersloot's 'INTERRUPTS IN QBASIC in this directory. He described the very first step 'in calling CALL ABSOLUTE and this article will introduce the logical 'second step. It will very basically describe the way in which you can 'use DATASEGMENTS in your assembler subs. 'The actual explanation will be done by working throught a very simple 'print string example. It is not ment to be anything fancy, but it is 'designed to be evident. DECLARE SUB dosprstr (string2write$) DECLARE FUNCTION int2str$ (sword%) DECLARE SUB Pokestring (SEGJE%, OFFJE%, MAIN$) dosprstr "What are we going to do ?" END SUB dosprstr (string2write$) '------------------------------------------------------------------------- 'DATA a% = LEN(string2write$) + 1: DIM datas%(a% \ 2 + 1) '----------------------------- 'INTRODUCTION ON DATASEGMENTS: '------------------------------ 'DATAS will be our datasegment. Take good care that we declare it as an 'array since arrays start at segment bounderies. That way we will not be 'surprised by segment changes. This might be trivial but when you use 'a simple variable which is number Xth in the row of variables it just might 'be that your starting adress is at seg:&hfffe. Same holds for stringvariables. 'They do not start at segmentbounderies too. Another feature of strings 'is that they walk around in memory due to garbage collection, making a 'string very unsuited for adressability purposes. So: we use DATAS% and poke 'our variables and strings just inside it! 'The length of the datasegment in this example is designed to keep only 'the string. b$ = string2write$ + "$" 'This is the way DOS processes stringprint '-------------------------------- 'MAKE THE DATASEGMENT ADRESSABLE: '-------------------------------- 'Here is the basic upset of an adressable datasegment: dataseg% = VARSEG(datas%(0)): dataoff% = VARPTR(datas%(0)) dataseg$ = int2str$(dataseg%): dataoff$ = int2str$(dataoff%) 'Next we poke our string into the datasegment. Pokestring dataseg%, dataoff%, b$ '----------------------------------- 'CODE 'push ax 'push dx 'push ds 'mov ax,dataseg$ 'mov ds,ax 'mov dx,dataoff$ 'mov ah,09 'printstring with ending $ 'int 21 'pop ds 'pop dx 'pop ax 'retf '----------------------------------- 'pusha asm$ = asm$ + CHR$(&H50) asm$ = asm$ + CHR$(&H52) asm$ = asm$ + CHR$(&H1E) asm$ = asm$ + CHR$(&HB8) + dataseg$ 'MOV AX,DATASEG$ asm$ = asm$ + CHR$(&H8E) + CHR$(&HD8) 'MOV DS,AX asm$ = asm$ + CHR$(&HBA) + dataoff$ 'MOV DX,DATAOFF$ asm$ = asm$ + CHR$(&HB4) + CHR$(&H9) 'MOV AH,9 asm$ = asm$ + CHR$(&HCD) + CHR$(&H21) 'INT 21 'popa asm$ = asm$ + CHR$(&H1F) asm$ = asm$ + CHR$(&H5A) asm$ = asm$ + CHR$(&H58) 'retf asm$ = asm$ + CHR$(&HCB) '________________________________________ Codeoff% = SADD(asm$) DEF SEG = VARSEG(asm$) CALL ABSOLUTE(Codeoff%) '________________________________________ DEF SEG END SUB FUNCTION int2str$ (sword%) 'This function is translating SWORD Integers into a string. Its only use 'is when you still use asm$ for assembler functions( like i do). In that 'case you can make your integer values usable .. 'THis function simply translates the hexa bytes 'into stringbytes as is. '---------------------------------------------------- DEF SEG = VARSEG(sword%) ptr% = VARPTR(sword%) int2str$ = CHR$(PEEK(ptr%)) + CHR$(PEEK(ptr% + 1)) DEF SEG END FUNCTION SUB Pokestring (SEGJE%, OFFJE%, MAIN$) '------------------------------------------------------ 'This function pokes a string (might be ASCIIZ)into 'memory at a given location, making it possible to 'access strings in byte form '------------------------------------------------------ DEF SEG = SEGJE% FOR i% = 0 TO LEN(MAIN$) - 1 POKE OFFJE% + i%, ASC(MID$(MAIN$, i% + 1, 1)) NEXT DEF SEG END SUB