Pointers

information about SharpBASIC language elements
Post Reply
User avatar
frank
Site Admin
Posts: 40
Joined: Sun Nov 21, 2021 12:04 pm
Location: Netherlands
Contact:

Pointers

Post by frank »

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.

In the following example a fixed-length string s with size 19, a pointer p and an unsigned integer n are declared. With the built-in function aof() (address of) 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 built-in function bya() (by address).

Code: Select all

' SharpBASIC ptr6
' -----------------
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;
Output:
Image
Keep it simple!
User avatar
frank
Site Admin
Posts: 40
Joined: Sun Nov 21, 2021 12:04 pm
Location: Netherlands
Contact:

Re: Pointers

Post by frank »

We can take the previous example a step further and get the value of each character of a string:

Code: Select all

' SharpBASIC ptr7
' -----------------
incl "lib/sys.sbi";

dim is
  s: str * 19;
  p_desc, p_addr: ptr;
  i, n: uint;
  v: uint8;
end;

main do
  s = "SharpBASIC is here!";
  ' 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
  count i up 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 datatype 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.

Output:
Image
Keep it simple!
User avatar
frank
Site Admin
Posts: 40
Joined: Sun Nov 21, 2021 12:04 pm
Location: Netherlands
Contact:

Re: Pointers

Post by frank »

While it is easy to obtain the address of a string using the general pointer functions aof and bya:

Code: Select all

' address of descriptor
p_desc = aof(s);
' string address
p_addr = bya(p_desc);
or:

Code: Select all

p_addr = bya(aof(s));
SharpBASIC has a special string function called sadd (string address), which is faster and easier to read:

Code: Select all

p_addr = sadd(s);
The following example uses sadd and bya to convert a hexadecimal string to a decimal number.

Code: Select all

' SharpBASIC hex to dec
' ---------------------
option strict;

incl "lib/sys.sbi";

dim hex: str = "7FFF";
dim p: ptr;
dim dec: 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 = b - 87;
      is 65 to 70 do      ' A..F = 10..15
        b = b - 55;
      is 48 to 57 do      ' 0..9
        b = b - 48;
      is other do
        break;
    end;
    dec = dec * 16 + b;
    p = p + 1;
  end;
  print(dec);
end;
output: 32767
Keep it simple!
User avatar
frank
Site Admin
Posts: 40
Joined: Sun Nov 21, 2021 12:04 pm
Location: Netherlands
Contact:

Re: Pointers

Post by frank »

There are three more pointer related subroutines that allow data to be written to specific memory locations. These subroutines are stob (store byte), stow (store word) and stod (store dword) and have the following syntax:

Code: Select all

stob(<pointer>, <value>)
stow(<pointer>, <value>)
stod(<pointer>, <value>)
The value can be numeric or character. For example, to write the one byte character 'A' (ascii code 65) to memory, both of the following statements are valid:

Code: Select all

stob(pointer, "A")
stob(pointer, 65)
The following example converts an integer to its binary string representation. For this, a 64 byte fixed length string is used. The function sadd returns the pointer to the string address. 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 mid string function returns the binary representation starting where variable n left off.

Code: Select all

func dec2bin(d: uint): str
  dim n: uint;
  dim r: str * 64;
  dim p: ptr;
do
  p = sadd(r);
  n = len(r);
  
  if d == 0 do
    n = n - 1;
    stob(p + n, "0");
  end;

  loop do
    while d > 0;
    n = n - 1;
    ' d modulo 2 + 48 stores 0 or 1
    stob(p + n, d % 2 + 48);
    d = d / 2;
  end;
  ' mid positions are one based, therefore n + 1
  dec2bin = mid(r, n + 1);
end;
Keep it simple!
Post Reply