# a little more...

Moderator

You're welcome.

One other thing:

You can use VARSEG() and VARPTR() to find the address of variables. This works well for numeric variables and fixed length strings.

fixed length string example:

----------

DECLARE FUNCTION hexb\$ (n AS INTEGER)
DIM i AS INTEGER
DIM t AS STRING * 5

t = "abcde"

CLS

DEF SEG = VARSEG(t)

FOR i = 0 TO LEN(t) - 1
PRINT "&h"; hexb(PEEK(VARPTR(t) + i)); ",";
NEXT i
PRINT

POKE VARPTR(t) + 2, 2 'insert a smiley face in the middle of the string

PRINT t
END

FUNCTION hexb\$ (n AS INTEGER)
DIM t AS STRING
t = LCASE\$(HEX\$(n))
IF 1 = LEN(t) THEN t = "0" + t
hexb = t
END FUNCTION

----------

You can do the same with the numeric types. INTEGERs are 2 bytes long, LONGs and SINGLEs are 4 bytes, DOUBLEs are 8 bytes. You can see how the numbers are actually stored. The integers (INTEGER and LONG) are stored in little endian (meaining the bytes are in low to high order). The floats (SINGLE and DOUBLE) are in IEEE 757-1985 format.

(You'll find that this concept is related to the ASC, CVI, CVL, CVS, CVD, CHR\$, MKI\$, MKL\$, MKS\$, MKD\$ family of functions.)

Here is an example demonstrating reading a LONG:

----------

DECLARE FUNCTION hexb\$ (n AS INTEGER)
DIM i AS INTEGER
DIM t AS LONG

t = &H12345678

CLS

DEF SEG = VARSEG(t)

FOR i = 0 TO LEN(t) - 1
PRINT "&h"; hexb(PEEK(VARPTR(t) + i)); ",";
NEXT i
PRINT
END

FUNCTION hexb\$ (n AS INTEGER)
DIM t AS STRING
t = LCASE\$(HEX\$(n))
IF 1 = LEN(t) THEN t = "0" + t
hexb = t
END FUNCTION

----------

Variable length strings are a little trickier. There is a function, SADD(), that returns the actual address of the string, but you want to be careful with that, because QBASIC moves variable length strings around. You should consider the address of the string to be fairly volatile. VARPTR() will give you the location of the string descriptor, which is a 4 byte structure that contains both the address of the string, and it's current length. You shouldn't manipulate the descriptor manually, and you should only use the address of the string itself if you are confident that it won't move while you're using it.

Also, dynamic arrays can move when you resize them (the segment can change).

Note: this all applies to QBASIC 1.1. PDS/QBX 7.1 added far strings. QB64, while it does a good job of emulating QBASIC 1.1, has it's own abilities and ways of doing things, although some of the same concepts apply.

----------

If you like playing around with direct memory access, you might like to have a browse through the rest of the assembly language forum:

http://www.network54.com/Forum/632471/

(The link that I gave you before was to a post I had written as part of a mini-"tutorial" in that forum.)

In that forum, Artelius gave a link to a book:
http://www.petesqbsite.com/sections/tutorials/tutorials/winer.zip

Just keep in mind that anything dealing with real mode memory access and/or DOS is pretty much obsolete. If you decide to learn assembly language, for example, don't get stuck on just the real mode and/or DOS stuff.

Regards,
Michael

Posted on Jul 18, 2012, 8:35 AM