Difference between revisions of "Address of a variable"

From BeebWiki
Jump to: navigation, search
m (1 revision)
m (Correct parameter order.)
Line 11: Line 11:
 
==6502==
 
==6502==
 
     DEFFNAddrOf_65:DIM A% 31:P%=A%
 
     DEFFNAddrOf_65:DIM A% 31:P%=A%
     [OPT2:LDA &604:STA &70:LDA &605:STA &71:LDY #0
+
     [OPT2:LDA &601:STA &70:LDA &602:STA &71:LDY #0
     LDA &601:STA (&70),Y:INY:LDA &602:STA (&70),Y:INY
+
     LDA &604:STA (&70),Y:INY:LDA &605:STA (&70),Y:INY
 
     LDA #0:STA (&70),Y:INY:STA (&70),Y:RTS:]:=A%
 
     LDA #0:STA (&70),Y:INY:STA (&70),Y:RTS:]:=A%
  
 
==Z80==
 
==Z80==
 
     DEFFNAddrOf_Z80:DIM A% 23:P%=A%
 
     DEFFNAddrOf_Z80:DIM A% 23:P%=A%
     [OPT 2:LD L,(IX+5):LD H,(IX+6):LD A,(IX+2):LD (HL),A
+
     [OPT 2:LD L,(IX+2):LD H,(IX+3):LD A,(IX+5):LD (HL),A
     INC HL:LD A,(IX+3):LD (HL),A:INC HL:LD (HL),0:INC HL
+
     INC HL:LD A,(IX+6):LD (HL),A:INC HL:LD (HL),0:INC HL
 
     LD (HL),0:RET:]:=A%
 
     LD (HL),0:RET:]:=A%
  
Line 28: Line 28:
  
 
     DEFFNAddrOf_86:DIM A% 19:P%=A%
 
     DEFFNAddrOf_86:DIM A% 19:P%=A%
     [OPT 2:MOV AX,DS:[BP+2]:MOV BX,DS:[BP+5]:MOV DS:[BX],AX
+
     [OPT 2:MOV AX,DS:[BP+5]:MOV BX,DS:[BP+2]:MOV DS:[BX],AX
 
     MOV AX,0:MOV DS:[BX+2],AX:RETF:]:=A%
 
     MOV AX,0:MOV DS:[BX+2],AX:RETF:]:=A%
  
Line 40: Line 40:
 
does not have an inline assembler, and the code must be created manually.
 
does not have an inline assembler, and the code must be created manually.
  
     DEFFNAddrOf_PDP:DIM A% 15:!A%=&C1D80:A%!4=&81D81:A%!8=&A311009:A%!12=870002:=A%
+
     DEFFNAddrOf_PDP:DIM A% 15:!A%=&81D80:A%!4=&C1D81:A%!8=&A311009:A%!12=870002:=A%
  
 
This creates the following code:
 
This creates the following code:
  
     MOV 12(SP),R0:MOV 8(SP),R1:MOV R0,(R1):CLR 2(R1):RTS PC
+
     MOV 8(SP),R0:MOV 12(SP),R1:MOV R0,(R1):CLR 2(R1):RTS PC
  
 
==32016==
 
==32016==
Line 50: Line 50:
 
==ARM==
 
==ARM==
 
     DEFFNAddrOf_ARM:DIM A% 15
 
     DEFFNAddrOf_ARM:DIM A% 15
     [OPT2:LDR R0,[R9]:LDR R1,[R9,#8]:STR R1,[R0]:MOV PC,R14:]:=A%
+
     [OPT2:LDR R0,[R9,#8]:LDR R1,[R9]:STR R1,[R0]:MOV PC,R14:]:=A%
  
 
==Usage==
 
==Usage==
Line 56: Line 56:
 
machine code, for instance <code>addrof%=FNAddrOf_65</code>, then the
 
machine code, for instance <code>addrof%=FNAddrOf_65</code>, then the
 
address of a variable can be found with
 
address of a variable can be found with
<code>CALL addrof%,variable,result%</code>, leaving the address in
+
<code>CALL addrof%,result%,variable</code>, leaving the address in
<code>result%</code>. <code>result%</code> must be a pre-existing integer
+
<code>result%</code>. Note that <code>result%</code> must be a pre-existing
variable. CALLing <code>addrof%</code> with fewer than two parameters, or
+
integer variable. CALLing <code>addrof%</code> with fewer than two parameters,
with a non-integer result will have undefined results.
+
or with a non-integer result will have undefined results.
  
 
BBC BASIC for Windows allows <code>^PROCname</code> and
 
BBC BASIC for Windows allows <code>^PROCname</code> and
Line 71: Line 71:
 
{| cellpadding="0" cellspacing="0"
 
{| cellpadding="0" cellspacing="0"
 
|- valign="top"
 
|- valign="top"
| <code>CALL addrof%,num,result%</code>  &nbsp;|| result% -> 5-byte floating point value
+
| <code>CALL addrof%,result%,num</code>  &nbsp;|| result% -> 5-byte floating point value
 
|- valign="top"
 
|- valign="top"
| <code>CALL addrof%,num%,result%</code> &nbsp;|| result% -> 4-byte integer value
+
| <code>CALL addrof%,result%,num%</code> &nbsp;|| result% -> 4-byte integer value
 
|- valign="top"
 
|- valign="top"
| <code>CALL addrof%,str$,result%</code> &nbsp;|| result% -> string information block
+
| <code>CALL addrof%,result%,str$</code> &nbsp;|| result% -> string information block
 
|}
 
|}
  
Line 89: Line 89:
  
 
     REM Load 4-byte file into a variable
 
     REM Load 4-byte file into a variable
     fred%=0:addr%=0:CALL addrof%,fred%,addr%
+
     fred%=0:addr%=0:CALL addrof%,addr%,fred%
 
     OSCLI "LOAD data "+STR$~A%
 
     OSCLI "LOAD data "+STR$~A%
  
Line 95: Line 95:
 
     big%=&12345678
 
     big%=&12345678
 
     little%=big%
 
     little%=big%
     CALL addrof%,little%,A%
+
     CALL addrof%,A%,little%
 
     tmp%=A%?0:A%?0=A%?3:A%?3=tmp%
 
     tmp%=A%?0:A%?0=A%?3:A%?3=tmp%
 
     tmp%=A%?1:A%?1=A%?2:A%?2=tmp%
 
     tmp%=A%?1:A%?1=A%?2:A%?2=tmp%

Revision as of 23:53, 28 March 2018

BBC BASIC for Windows implements the ^identifier function (as opposed to the num ^ num operator) to return the address of a variable. For example, ^fred% returns the address where the data for the variable fred% is stored.

This can be implemented on other versions of BBC BASIC with the following code, which is also available in the AddrOf BASIC library.

6502

   DEFFNAddrOf_65:DIM A% 31:P%=A%
   [OPT2:LDA &601:STA &70:LDA &602:STA &71:LDY #0
   LDA &604:STA (&70),Y:INY:LDA &605:STA (&70),Y:INY
   LDA #0:STA (&70),Y:INY:STA (&70),Y:RTS:]:=A%

Z80

   DEFFNAddrOf_Z80:DIM A% 23:P%=A%
   [OPT 2:LD L,(IX+2):LD H,(IX+3):LD A,(IX+5):LD (HL),A
   INC HL:LD A,(IX+6):LD (HL),A:INC HL:LD (HL),0:INC HL
   LD (HL),0:RET:]:=A%

6809

80186

BBC BASIC for Windows implements ^identifier. DOS BASIC does not, and the following code must be used.

   DEFFNAddrOf_86:DIM A% 19:P%=A%
   [OPT 2:MOV AX,DS:[BP+5]:MOV BX,DS:[BP+2]:MOV DS:[BX],AX
   MOV AX,0:MOV DS:[BX+2],AX:RETF:]:=A%


PDP-11

PDP-11 BASIC implements ^identifier natively. The following code can be used for compatibility. Current versions of PDP-11 BASIC does not have an inline assembler, and the code must be created manually.

   DEFFNAddrOf_PDP:DIM A% 15:!A%=&81D80:A%!4=&C1D81:A%!8=&A311009:A%!12=870002:=A%

This creates the following code:

   MOV 8(SP),R0:MOV 12(SP),R1:MOV R0,(R1):CLR 2(R1):RTS PC

32016

ARM

   DEFFNAddrOf_ARM:DIM A% 15
   [OPT2:LDR R0,[R9,#8]:LDR R1,[R9]:STR R1,[R0]:MOV PC,R14:]:=A%

Usage

Once the appropriate FNAddrOf_* function is called to set up the machine code, for instance addrof%=FNAddrOf_65, then the address of a variable can be found with CALL addrof%,result%,variable, leaving the address in result%. Note that result% must be a pre-existing integer variable. CALLing addrof% with fewer than two parameters, or with a non-integer result will have undefined results.

BBC BASIC for Windows allows ^PROCname and ^FNname. This code only supports those variables that can be passed to the CALL command.

After calling, result% holds the address of the variable's data block, as with parameters passed to CALL. This will be the following:

CALL addrof%,result%,num   result% -> 5-byte floating point value
CALL addrof%,result%,num%   result% -> 4-byte integer value
CALL addrof%,result%,str$   result% -> string information block

The string information block is different on different platforms. See CALL for details.

Examples

   REM Print exponent of PI
   num=PI
   CALL addrof%,num,A%
   PRINT "Exponent: ";?A%
   REM Load 4-byte file into a variable
   fred%=0:addr%=0:CALL addrof%,addr%,fred%
   OSCLI "LOAD data "+STR$~A%
   REM Swap byte order
   big%=&12345678
   little%=big%
   CALL addrof%,A%,little%
   tmp%=A%?0:A%?0=A%?3:A%?3=tmp%
   tmp%=A%?1:A%?1=A%?2:A%?2=tmp%


Jgharston 00:06, 5 December 2009 (UTC)