'=========================================================================== ' Subject: ASSEMBLY IN QBASIC 2: INSIDE Date: 02-07-97 (22:15) ' Author: Rick Elbers Code: QB, QBasic, PDS ' Origin: rick@tip.nl Packet: ASMCODE.ABC '=========================================================================== 'ASSEMBLY IN QBASIC 2: DEFAULTS '----------------------------------------------------------------------- 'Rick Elbers februari 1997 '-------------------------- 'Introduction '-------------- 'This routine is exploring the values for DS,ES,SS,SP and the return adresses 'as they depend on both the CS:IP you have set by storing the asm routine 'and on the QBASIC IDE environment. 'Both asm$ storage and integer storage design are considered. '--------------------------------------------------------------------------- DEFINT A-Z DECLARE SUB inside2 (dat()) 'INITIALIZING: CLS : DIM dat(18): header$ = CHR$(179) + " CS " + CHR$(179) + " IP " + CHR$(179) + " DS " header$ = header$ + CHR$(179) + " ES " + CHR$(179) + " SS " + CHR$(179) header$ = header$ + " SP " + CHR$(179) + "RECS" + CHR$(179) + "REIP" header$ = header$ + CHR$(179) + "flag" + CHR$(179) 'EXECUTE: inside2 dat() 'PRINT: COLOR 0, 7: PRINT SPACE$(13) + "WITH ASM$ APPROACH" + SPACE$(15) COLOR 7, 0: PRINT STRING$(46, "_"): PRINT header$: COLOR 0, 7 PRINT CHR$(179); FOR i = 9 TO 17: a$ = HEX$(dat(i)): PRINT STRING$(4 - LEN(a$), "0") + a$ + CHR$(179); NEXT PRINT : PRINT COLOR 0, 7: PRINT SPACE$(10) + "INTEGER STORAGE APPROACH" + SPACE$(12) COLOR 7, 0: PRINT STRING$(46, "_"): PRINT header$: COLOR 0, 7 PRINT CHR$(179); FOR i = 0 TO 8: a$ = HEX$(dat(i)): PRINT STRING$(4 - LEN(a$), "0") + a$ + CHR$(179); NEXT PRINT : PRINT 'Now let us go for the three sorts of space IN QBASIC: COLOR 0, 7: PRINT SPACE$(5) + "SPACES INSIDE QBASIC" + SPACE$(5): COLOR 7, 0: PRINT STRING$(30, "_") PRINT "Stringspace : "; HEX$(FRE("")) PRINT "Array(heap) space : "; HEX$(FRE(-1)) PRINT "Stackspace : "; HEX$(FRE(-2)) PRINT STRING$(30, "_") '1) Take notice that DS=CS=SS=stringsegment for ASM$ and DS=SS for ' integerstorage. The importance of this information can hardly be ' overestimated. ' In some other contributions you can see that because of DS=SS ' you can set up a pointer to a variable his adress on the stack, ' and because of DS=stringsegment you do not have to assign DS ' anoter value in a lot of cases. '2) Take a notice that an array startadress is always at a paragraphs ' boundery, so you do not need to pass the offset through the stack. ' You can just put it to zero. '3) Since there is only one stringsegment, it is also not necessary to ' redeclare the segment with DEF SEG in a lot of cases. Just leave it ' pointing to the string/stack segment will do. 'The use of the mentioned consequences will demonstrated in later articles. 'Good bye. 'Rick SUB inside2 (dat()) '------------------------------------------------------------------------- ' [var]BP+6 '------------------------------------------------------------------------ asm$ = "" 'SP( on entrance ' SS:SP-0 =: CS BP+4 ' SS:SP-2 =: IP BP+2 asm$ = asm$ + CHR$(&H55) 'push bp SS:SP-4 BP+0 asm$ = asm$ + CHR$(&H89) + CHR$(&HE5) 'mov bp,sp asm$ = asm$ + CHR$(&H1E) 'push ds SS:SP-6 '--------------------------------- ^ 'First make our DAT adressable: backwards '--------------------------------- asm$ = asm$ + CHR$(&H8B) + CHR$(&H5E) + CHR$(6) 'mov bx,[bp+06] asm$ = asm$ + CHR$(&HC5) + CHR$(&H37) 'lds si,[bx] '------------------------------------------------- 'Now let us pop the returns adress of the stack: '------------------------------------------------- asm$ = asm$ + CHR$(&H8B) + CHR$(&H5E) + CHR$(&H2) 'mov bx,[bp+&h2] asm$ = asm$ + CHR$(&H89) + CHR$(&H5C) + CHR$(14) 'mov [si+e],bx asm$ = asm$ + CHR$(&H8B) + CHR$(&H5E) + CHR$(&H4) 'mov bx,[bp+&h4] asm$ = asm$ + CHR$(&H89) + CHR$(&H5C) + CHR$(12) 'mov [si+c],bx '-------------------------------- 'Now store ds,es,ss,sp and flags: '-------------------------------- asm$ = asm$ + CHR$(&H58) 'pop ax get ds to ax asm$ = asm$ + CHR$(&H89) + CHR$(&H44) + CHR$(4) 'mov [si+4],ax store ds asm$ = asm$ + CHR$(&H8C) + CHR$(&H44) + CHR$(6) 'mov [si+6],ES store es asm$ = asm$ + CHR$(&H9C) 'pushf asm$ = asm$ + CHR$(&H8F) + CHR$(&H44) + CHR$(16) 'pop [si+&h10] store flags asm$ = asm$ + CHR$(&H8C) + CHR$(&H54) + CHR$(8) 'mov [si+8],ss store ss asm$ = asm$ + CHR$(&H83) + CHR$(&HC5) + CHR$(&H2)'add bp,2 'to sp on entrance (only push bp is in between) asm$ = asm$ + CHR$(&H89) + CHR$(&H6C) + CHR$(10) 'mov [si+a],bp store sp '-------------------- 'Restore ds and bp: '-------------------- asm$ = asm$ + CHR$(&H8E) + CHR$(&HD8) 'mov ds,ax asm$ = asm$ + CHR$(&H5D) 'pop bp '------------- 'We are done? '------------- asm$ = asm$ + CHR$(&HCA) + MKI$(2) 'retf 2 dat(9) = VARSEG(asm$): dat(10) = SADD(asm$): 'STORE CS[IP] DEF SEG = dat(9): CALL absolute(dat(), dat(10)) 'EXECUTE asm$ FOR i = 2 TO 8: dat(i + 9) = dat(i): NEXT 'STORE IN dat(8..17) DIM asmI(LEN(asm$) \ 2 + 1): 'INTEGERSTORAGE dat(0) = VARSEG(asmI(0)): dat(1) = VARPTR(asmI(0)) 'STORE CS[IP] DEF SEG = dat(0) 'POKE ASM$ IN ARRAY FOR i = 0 TO LEN(asm$) - 1: POKE i, ASC(MID$(asm$, i + 1, 1)) NEXT CALL absolute(dat(), dat(1)): DEF SEG 'EXECUTE asmI() END SUB