Difference between revisions of "Address of a variable"
m (1 revision) |
m (→PDP-11) |
||
(One intermediate revision by the same user not shown) | |||
Line 11: | Line 11: | ||
==6502== | ==6502== | ||
DEFFNAddrOf_65:DIM A% 31:P%=A% | DEFFNAddrOf_65:DIM A% 31:P%=A% | ||
− | [OPT2:LDA & | + | [OPT2:LDA &601:STA &70:LDA &602:STA &71:LDY #0 |
− | LDA & | + | 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+ | + | [OPT 2:LD L,(IX+2):LD H,(IX+3):LD A,(IX+5):LD (HL),A |
− | INC HL:LD A,(IX+ | + | 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+ | + | [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 | + | 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 | + | MOV 8(SP),R0:MOV 12(SP),R1:MOV R0,(R1):CLR 2(R1):RTS PC |
==32016== | ==32016== | ||
Line 50: | Line 51: | ||
==ARM== | ==ARM== | ||
DEFFNAddrOf_ARM:DIM A% 15 | DEFFNAddrOf_ARM:DIM A% 15 | ||
− | [OPT2:LDR R0,[R9]:LDR R1,[R9 | + | [OPT2:LDR R0,[R9,#8]:LDR R1,[R9]:STR R1,[R0]:MOV PC,R14:]:=A% |
==Usage== | ==Usage== | ||
Line 56: | Line 57: | ||
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% | + | <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 72: | ||
{| cellpadding="0" cellspacing="0" | {| cellpadding="0" cellspacing="0" | ||
|- valign="top" | |- valign="top" | ||
− | | <code>CALL addrof% | + | | <code>CALL addrof%,result%,num</code> || result% -> 5-byte floating point value |
|- valign="top" | |- valign="top" | ||
− | | <code>CALL addrof%, | + | | <code>CALL addrof%,result%,num%</code> || result% -> 4-byte integer value |
|- valign="top" | |- valign="top" | ||
− | | <code>CALL addrof%,str$ | + | | <code>CALL addrof%,result%,str$</code> || result% -> string information block |
|} | |} | ||
Line 89: | Line 90: | ||
REM Load 4-byte file into a variable | REM Load 4-byte file into a variable | ||
− | fred%=0:addr%=0:CALL addrof%, | + | fred%=0:addr%=0:CALL addrof%,addr%,fred% |
OSCLI "LOAD data "+STR$~A% | OSCLI "LOAD data "+STR$~A% | ||
Line 95: | Line 96: | ||
big%=&12345678 | big%=&12345678 | ||
little%=big% | little%=big% | ||
− | CALL addrof%, | + | 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% |
Latest revision as of 01:55, 10 February 2022
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)