Table of Contents
Pointers
SharpBASIC has a general pointer type ptr. It is general in that it will not bind to a specific type. Hence there is no type checking other than the pointer type itself (optionally enforced by the option strict directive). So pointers can point to any address and it is up to the programmer to take responsibility when using pointers.
read-memory functions
SharpBASIC has built-in functions for reading memory. These functions are:
- aof() - address of
- bya() - by address
- sadd() - string address
In the following example a fixed-length string s with size 19, a pointer p and an unsigned integer n are declared. With the function aof() the descriptor address of string s is assigned to p. In SharpBASIC a string descriptor has the format [addr:size], a double dword in 32-bits. So p + 4 points to the size of the string and is assigned to n with the function bya().
option strict
incl "lib/sys.sbi";
dim s: str * 19;
dim p: ptr;
dim n: uint;
main do
' address of descriptor
p = aof(s);
' size by address in second dword field
n = bya(p + 4);
' output: 19
print(n);
end
We can take the previous example a step further and get the value of each character of the string:
option strict
incl "lib/sys.sbi";
dim is
s: str * 19 = "SharpBASIC is here!";
p_desc, p_addr: ptr;
n: uint;
i: uitr;
v: uint8;
end
main do
' address of descriptor
p_desc = aof(s);
' string address
p_addr = bya(p_desc);
' string size
n = bya(p_desc + 4);
' print each character's value
for i = 0 to n - 1 :++ do
v = bya(p_addr + i);
print(v);
end
end
See how the function bya() is used three times and expected to return a different data type each time, including a pointer! In the loop we want the byte value stored at p_addr + i, so we declared v: uint8, which tells bya() that we want the byte value at the specified address.
If we do not need the descriptor address of a variable or fixed-length string, we can use the function sadd() to obtain the address of a string directly. The following example uses sadd() and bya() to convert a hexadecimal string to a decimal number.
option strict;
incl "lib/sys.sbi";
dim hex: str = "7FFF";
dim p: ptr;
dim r: uint = 0;
dim b: uint8;
main do
p = sadd(hex);
loop do
b = bya(p):++;
when b
is 97 to 102 do ' a..f = 10..15
b:-87;
is 65 to 70 do ' A..F = 10..15
b:-55;
is 48 to 57 do ' 0..9
b:-48;
is other do
break;
end
r:*16+b;
end
print(r);
end
write-memory subroutines
SharpBASIC has built-in subroutines that allow data to be written to memory. These subroutines are:
- stob() - store byte
- stow() - store word
- stod() - store dword
- stoq() - store qword
The value to be written to memory can be numeric or string. For example, to write the one byte character 'A' (ascii code 65) to memory, both of the following statements are valid:
stob(pointer, "A");
stob(pointer, 65);
The following example converts an integer to its binary string representation. For this, a 64-bytes fixed length string is used. With the function sadd() the string address is assigned to p. Variable n then starts counting from byte 64 backwards so that the bits can be put at the right position in the string with the subroutine stob(). Finally, the string function mid() returns the binary representation starting where variable n left off.
func int2bin(d: int): str
dim n: uint;
dim r: str * 64;
dim p: ptr;
do
p = sadd(r);
n = len(r);
if d == 0 do
n:--;
stob(p + n, "0");
end
loop do
while d > 0;
n:--;
' d modulo 2 + 48 stores 0 or 1
stob(p + n, d % 2 + 48);
d:/2;
end
' mid positions are one based, therefore n + 1
int2bin = mid(r, n + 1);
end