Address of a variable: Difference between revisions
Content added Content deleted
Thundergnat (talk | contribs) m (syntax highlighting fixup automation) |
|||
Line 9: | Line 9: | ||
===Get the Address=== |
===Get the Address=== |
||
To get the address of a variable, use <code>LA</code> (load address) instead of <code>L</code> (load): |
To get the address of a variable, use <code>LA</code> (load address) instead of <code>L</code> (load): |
||
< |
<syntaxhighlight lang=360asm> LA R3,I load address of I |
||
... |
... |
||
I DS F</ |
I DS F</syntaxhighlight> |
||
===Set the Address=== |
===Set the Address=== |
||
To set a variable dynamically at the same address of an other variable, use a <code>DSECT</code> (dummy section): |
To set a variable dynamically at the same address of an other variable, use a <code>DSECT</code> (dummy section): |
||
< |
<syntaxhighlight lang=360asm> USING MYDSECT,R12 |
||
LA R12,I set @J=@I |
LA R12,I set @J=@I |
||
L R2,J now J is at the same location as I |
L R2,J now J is at the same location as I |
||
Line 21: | Line 21: | ||
I DS F |
I DS F |
||
MYDSECT DSECT |
MYDSECT DSECT |
||
J DS F</ |
J DS F</syntaxhighlight> |
||
=={{header|6502 Assembly}}== |
=={{header|6502 Assembly}}== |
||
When programming in assembly language yourself, generally the addresses of variables are known in advance and chosen by the programmer rather than dynamically determined by the compiler. Loading values from RAM into memory requires the programmer to specify the address as the operand. This is true for zero-page memory, absolute memory addresses, and memory-mapped ports whose location is defined by the hardware manufacturer. Typically, the assembly programmer will use labels to ease this process, which get converted to memory addresses automatically when the program is assembled. |
When programming in assembly language yourself, generally the addresses of variables are known in advance and chosen by the programmer rather than dynamically determined by the compiler. Loading values from RAM into memory requires the programmer to specify the address as the operand. This is true for zero-page memory, absolute memory addresses, and memory-mapped ports whose location is defined by the hardware manufacturer. Typically, the assembly programmer will use labels to ease this process, which get converted to memory addresses automatically when the program is assembled. |
||
< |
<syntaxhighlight lang=6502asm>;;;;;;; zero page RAM memory addresses |
||
CursorX equ $00 |
CursorX equ $00 |
||
CursorY equ $01 |
CursorY equ $01 |
||
Line 33: | Line 33: | ||
Joystick1 equ $DC01 |
Joystick1 equ $DC01 |
||
Joystick2 equ $DC00</ |
Joystick2 equ $DC00</syntaxhighlight> |
||
Rather than setting the address of a variable, in assembly the programmer stores a calculated quantity in an address. The terms "memory address" and "variable" are often used interchangably. |
Rather than setting the address of a variable, in assembly the programmer stores a calculated quantity in an address. The terms "memory address" and "variable" are often used interchangably. |
||
< |
<syntaxhighlight lang=6502asm>LDA #$20 ; load a constant into the accumulator |
||
CLC |
CLC |
||
Line 45: | Line 45: | ||
STA temp ; store the result in a temp variable (really a zero-page memory address). |
STA temp ; store the result in a temp variable (really a zero-page memory address). |
||
</syntaxhighlight> |
|||
</lang> |
|||
6502 assemblers treat a number without a # in front as a memory address. |
6502 assemblers treat a number without a # in front as a memory address. |
||
< |
<syntaxhighlight lang=6502asm>LDA #$30 ;load into the accumulator the constant value 0x30 |
||
LDA $30 ;load into the accumulator the value stored at memory address 0x0030.</ |
LDA $30 ;load into the accumulator the value stored at memory address 0x0030.</syntaxhighlight> |
||
The only exception to this rule is when defining bytes. These do not have # in front, but are treated as constants nonetheless: |
The only exception to this rule is when defining bytes. These do not have # in front, but are treated as constants nonetheless: |
||
< |
<syntaxhighlight lang=6502asm>byte $30,$20,$10,$00 ;these are constant numeric values, not memory addresses.</syntaxhighlight> |
||
=={{header|68000 Assembly}}== |
=={{header|68000 Assembly}}== |
||
When programming in assembly language yourself, generally the addresses of variables are known in advance and chosen by the programmer rather than dynamically determined by the compiler. Therefore you pretty much always know a variable's address at all times. |
When programming in assembly language yourself, generally the addresses of variables are known in advance and chosen by the programmer rather than dynamically determined by the compiler. Therefore you pretty much always know a variable's address at all times. |
||
< |
<syntaxhighlight lang=68000devpac>UserRam equ $100000 |
||
Cursor_X equ UserRam ;$100000, byte length |
Cursor_X equ UserRam ;$100000, byte length |
||
Cursor_Y equ UserRam+1 ;$100001, byte length |
Cursor_Y equ UserRam+1 ;$100001, byte length |
||
Line 65: | Line 65: | ||
;GET THE ADDRESS |
;GET THE ADDRESS |
||
LEA ThirtyTwoBitData,A0 ;load $100004 into A0.</ |
LEA ThirtyTwoBitData,A0 ;load $100004 into A0.</syntaxhighlight> |
||
Setting a variable to an address is as simple as storing a desired value in memory. Assembly languages in general do not have automated memory management, so it is important to manage your memory well. |
Setting a variable to an address is as simple as storing a desired value in memory. Assembly languages in general do not have automated memory management, so it is important to manage your memory well. |
||
< |
<syntaxhighlight lang=68000devpac>MOVE.L #$11223344,D0 |
||
MOVE.L D0,(A0) ; store D0 into ThirtyTwoBitData ($100004) |
MOVE.L D0,(A0) ; store D0 into ThirtyTwoBitData ($100004) |
||
; HEXDUMP OF $100004: |
; HEXDUMP OF $100004: |
||
Line 75: | Line 75: | ||
; $100005: $22 |
; $100005: $22 |
||
; $100006: $33 |
; $100006: $33 |
||
; $100007: $44</ |
; $100007: $44</syntaxhighlight> |
||
Line 83: | Line 83: | ||
{{works with|https://www.dosbox.com DOSBox}} |
{{works with|https://www.dosbox.com DOSBox}} |
||
===Get The Address=== |
===Get The Address=== |
||
< |
<syntaxhighlight lang=asm>.model small |
||
.stack 1024 |
.stack 1024 |
||
.data |
.data |
||
Line 94: | Line 94: | ||
mov ax, offset UserRam ;load into AX the address of UserRam |
mov ax, offset UserRam ;load into AX the address of UserRam |
||
mov di, ax ;load that value into the destination index register</ |
mov di, ax ;load that value into the destination index register</syntaxhighlight> |
||
The actual numeric value of the address isn't needed, as the label system takes care of that for us. A memory dump routine can show the contents of <code>es:di</code>, displaying the actual memory location. |
The actual numeric value of the address isn't needed, as the label system takes care of that for us. A memory dump routine can show the contents of <code>es:di</code>, displaying the actual memory location. |
||
Line 101: | Line 101: | ||
Like with other assembly languages, the terms "variable" and "memory address" are often interchangeable. Setting a variable to an address is just storing a value into memory. After the setup above has taken place, the programmer can store numbers into memory. |
Like with other assembly languages, the terms "variable" and "memory address" are often interchangeable. Setting a variable to an address is just storing a value into memory. After the setup above has taken place, the programmer can store numbers into memory. |
||
< |
<syntaxhighlight lang=asm>mov ax, 0FFFFh |
||
mov [es:di],ax ;store 0xFFFF into the base address of UserRam.</ |
mov [es:di],ax ;store 0xFFFF into the base address of UserRam.</syntaxhighlight> |
||
Alternatively, this would also work: |
Alternatively, this would also work: |
||
< |
<syntaxhighlight lang=asm>.model small |
||
.stack 1024 |
.stack 1024 |
||
.data |
.data |
||
Line 117: | Line 117: | ||
mov ax, 0FFFFh ; load the number 65535 (or -1 if you prefer) into ax. |
mov ax, 0FFFFh ; load the number 65535 (or -1 if you prefer) into ax. |
||
mov word ptr [ds:UserRam] ; store this quantity in user ram.</ |
mov word ptr [ds:UserRam] ; store this quantity in user ram.</syntaxhighlight> |
||
=={{header|AArch64 Assembly}}== |
=={{header|AArch64 Assembly}}== |
||
{{works with|as|Raspberry Pi 3B version Buster 64 bits}} |
{{works with|as|Raspberry Pi 3B version Buster 64 bits}} |
||
< |
<syntaxhighlight lang=AArch64 Assembly> |
||
/* ARM assembly AArch64 Raspberry PI 3B */ |
/* ARM assembly AArch64 Raspberry PI 3B */ |
||
/* program adrvar.s */ |
/* program adrvar.s */ |
||
Line 197: | Line 197: | ||
ret // retour adresse lr x30 |
ret // retour adresse lr x30 |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Action!}}== |
=={{header|Action!}}== |
||
< |
<syntaxhighlight lang=Action!>PROC Main() |
||
BYTE v=[123] |
BYTE v=[123] |
||
PrintF("Value of variable: %B%E",v) |
PrintF("Value of variable: %B%E",v) |
||
PrintF("Address of variable: %H%E",@v) |
PrintF("Address of variable: %H%E",@v) |
||
RETURN</ |
RETURN</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Address_of_a_variable.png Screenshot from Atari 8-bit computer] |
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Address_of_a_variable.png Screenshot from Atari 8-bit computer] |
||
Line 215: | Line 215: | ||
=={{header|Ada}}== |
=={{header|Ada}}== |
||
===Get The Address=== |
===Get The Address=== |
||
< |
<syntaxhighlight lang=ada>The_Address : System.Address; |
||
I : Integer; |
I : Integer; |
||
The_Address := I'Address;</ |
The_Address := I'Address;</syntaxhighlight> |
||
===Set The Address=== |
===Set The Address=== |
||
Set the address of a variable to address A100 in hexadecimal |
Set the address of a variable to address A100 in hexadecimal |
||
< |
<syntaxhighlight lang=ada>I : Integer; |
||
for I'Address use 16#A100#;</ |
for I'Address use 16#A100#;</syntaxhighlight> |
||
Set the address of one variable to the address of another variable, creating an overlay. |
Set the address of one variable to the address of another variable, creating an overlay. |
||
< |
<syntaxhighlight lang=ada>I : Integer; |
||
J : Integer; |
J : Integer; |
||
for I'Address use J'Address;</ |
for I'Address use J'Address;</syntaxhighlight> |
||
=={{header|ALGOL 68}}== |
=={{header|ALGOL 68}}== |
||
Line 233: | Line 233: | ||
But the value of the actual address is not available |
But the value of the actual address is not available |
||
for printing or any arithmetic. |
for printing or any arithmetic. |
||
< |
<syntaxhighlight lang=algol68>[4]INT test := (222,444,666,888); |
||
REF INT reference := test[3]; |
REF INT reference := test[3]; |
||
REF INT(reference) := reference + 111; |
REF INT(reference) := reference + 111; |
||
print(("test value is now: ",test))</ |
print(("test value is now: ",test))</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>test value is now: +222 +444 +777 +888</pre> |
<pre>test value is now: +222 +444 +777 +888</pre> |
||
Line 250: | Line 250: | ||
or to a filestore maintained by the operating system</i>[http://www.xs4all.nl/~jmvdveer/report_5.html#A312aa]. |
or to a filestore maintained by the operating system</i>[http://www.xs4all.nl/~jmvdveer/report_5.html#A312aa]. |
||
To establish a channel with such a device there is a special standard procedure:< |
To establish a channel with such a device there is a special standard procedure:<syntaxhighlight lang=algol68>PROC establish = (REF FILE file, STRING idf, CHANNEL chan, INT p, l, c) INT: ~</syntaxhighlight> |
||
Where the <tt>idf</tt> string is text describing which device to open, and possibly |
Where the <tt>idf</tt> string is text describing which device to open, and possibly |
||
options. And <tt>chan</tt> is the actual device type. Standard CHANNELs in |
options. And <tt>chan</tt> is the actual device type. Standard CHANNELs in |
||
Line 262: | Line 262: | ||
=== Get the address === |
=== Get the address === |
||
Get the address of the last variable used. |
Get the address of the last variable used. |
||
< |
<syntaxhighlight lang=ApplesoftBasic>N = N : PRINT PEEK (131) + PEEK (132) * 256</syntaxhighlight> |
||
Get (find) the address of a function. |
Get (find) the address of a function. |
||
< |
<syntaxhighlight lang=ApplesoftBasic>0 DEF FN F(X) = 0 |
||
1 FOR A = PEEK(105) + PEEK(106) * 256 TO PEEK(107) + PEEK(108) * 256 STEP 7 : IF PEEK(A) <> ASC("F") + 128 OR PEEK(A + 1) <> 0 THEN NEXT A : A = 0 : PRINT "FN F NOT FOUND" |
1 FOR A = PEEK(105) + PEEK(106) * 256 TO PEEK(107) + PEEK(108) * 256 STEP 7 : IF PEEK(A) <> ASC("F") + 128 OR PEEK(A + 1) <> 0 THEN NEXT A : A = 0 : PRINT "FN F NOT FOUND" |
||
2 IF A THEN PRINT A |
2 IF A THEN PRINT A |
||
</syntaxhighlight> |
|||
</lang> |
|||
=== Set the address === |
=== Set the address === |
||
Set the address where variables are stored, but clears all variables. |
Set the address where variables are stored, but clears all variables. |
||
< |
<syntaxhighlight lang=ApplesoftBasic>LOMEM: 4096 |
||
I% = I% : PRINT PEEK (131) + PEEK (132) * 256 |
I% = I% : PRINT PEEK (131) + PEEK (132) * 256 |
||
</syntaxhighlight> |
|||
</lang> |
|||
Set the address and length of a string. |
Set the address and length of a string. |
||
< |
<syntaxhighlight lang=ApplesoftBasic>S$ = "HELLO" : POKE 768, PEEK (131) : POKE 769, PEEK (132) : A = PEEK(768) + PEEK(769) * 256 |
||
PRINT S$ : PRINT A "- " PEEK(A) " " PEEK(A + 1) + PEEK(A + 2) * 256 |
PRINT S$ : PRINT A "- " PEEK(A) " " PEEK(A + 1) + PEEK(A + 2) * 256 |
||
POKE 768, ASC("H") : POKE 769, ASC("I") : POKE A, 2: POKE A + 1, 0 : POKE A + 2, 3 |
POKE 768, ASC("H") : POKE 769, ASC("I") : POKE A, 2: POKE A + 1, 0 : POKE A + 2, 3 |
||
PRINT S$ : PRINT A "- " PEEK(A) " " PEEK(A + 1) + PEEK(A + 2) * 256 |
PRINT S$ : PRINT A "- " PEEK(A) " " PEEK(A + 1) + PEEK(A + 2) * 256 |
||
</syntaxhighlight> |
|||
</lang> |
|||
Set the address of a function. |
Set the address of a function. |
||
< |
<syntaxhighlight lang=ApplesoftBasic>0 DEF FN F(X) = 1 |
||
1 DEF FN B(X) = 2 |
1 DEF FN B(X) = 2 |
||
2 N$ = "F" : GOSUB 8 : FA = A |
2 N$ = "F" : GOSUB 8 : FA = A |
||
Line 291: | Line 291: | ||
8 FOR A = PEEK(105) + PEEK(106) * 256 TO PEEK(107) + PEEK(108) * 256 STEP 7 : IF PEEK(A) = ASC(LEFT$(N$,1)) + 128 AND PEEK(A + 1) = ASC(MID$(N$ + CHR$(0), 2, 1)) THEN A = A + 2 : RETURN |
8 FOR A = PEEK(105) + PEEK(106) * 256 TO PEEK(107) + PEEK(108) * 256 STEP 7 : IF PEEK(A) = ASC(LEFT$(N$,1)) + 128 AND PEEK(A + 1) = ASC(MID$(N$ + CHR$(0), 2, 1)) THEN A = A + 2 : RETURN |
||
9 NEXT A : PRINT "FN " N$ " NOT FOUND" |
9 NEXT A : PRINT "FN " N$ " NOT FOUND" |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Argile}}== |
=={{header|Argile}}== |
||
=== Get the address === |
=== Get the address === |
||
{{works with|Argile|1.0.0}} |
{{works with|Argile|1.0.0}} |
||
< |
<syntaxhighlight lang=Argile>use std, array (: array.arg also defines pointer operators :) |
||
let var = 42 |
let var = 42 |
||
let ptr = &var (: value of ptr is address of var :) |
let ptr = &var (: value of ptr is address of var :) |
||
print var (: prints 42 :) |
print var (: prints 42 :) |
||
(*ptr)++ (: increments value pointed by ptr :) |
(*ptr)++ (: increments value pointed by ptr :) |
||
print var (: prints 43 :)</ |
print var (: prints 43 :)</syntaxhighlight> |
||
=== Set the address === |
=== Set the address === |
||
Since we cannot set address of a variable, we use a macro |
Since we cannot set address of a variable, we use a macro |
||
that returns a reference. |
that returns a reference. |
||
{{works with|Argile|1.0.0}} |
{{works with|Argile|1.0.0}} |
||
< |
<syntaxhighlight lang=Argile>use std, array |
||
=:mac:= -> int& { * (0x400000 as int*) } |
=:mac:= -> int& { * (0x400000 as int*) } |
||
printf "%x\n" mac (: may crash depending on operating system :) |
printf "%x\n" mac (: may crash depending on operating system :) |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|ARM Assembly}}== |
=={{header|ARM Assembly}}== |
||
{{works with|as|Raspberry Pi}} |
{{works with|as|Raspberry Pi}} |
||
< |
<syntaxhighlight lang=ARM Assembly> |
||
/* ARM assembly Raspberry PI */ |
/* ARM assembly Raspberry PI */ |
||
Line 384: | Line 384: | ||
bx lr /* retour procedure */ |
bx lr /* retour procedure */ |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Arturo}}== |
=={{header|Arturo}}== |
||
< |
<syntaxhighlight lang=rebol>x: 2 |
||
xInfo: info.get 'x |
xInfo: info.get 'x |
||
Line 394: | Line 394: | ||
"address of x:" xInfo\address |
"address of x:" xInfo\address |
||
"->" from.hex xInfo\address |
"->" from.hex xInfo\address |
||
]</ |
]</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 401: | Line 401: | ||
=={{header|Astro}}== |
=={{header|Astro}}== |
||
< |
<syntaxhighlight lang=python>var num = 12 |
||
var pointer = ptr(num) # get pointer |
var pointer = ptr(num) # get pointer |
||
Line 408: | Line 408: | ||
@unsafe # bad idea! |
@unsafe # bad idea! |
||
pointer.addr = 0xFFFE # set the address |
pointer.addr = 0xFFFE # set the address |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|AutoHotkey}}== |
=={{header|AutoHotkey}}== |
||
Getting or setting the address of a variable is not supported as a builtin function. |
Getting or setting the address of a variable is not supported as a builtin function. |
||
However, you can get the address of contents pointed to by the variable structure var |
However, you can get the address of contents pointed to by the variable structure var |
||
<lang |
<syntaxhighlight lang=AutoHotkey>msgbox % &var</syntaxhighlight> |
||
=={{header|Axe}}== |
=={{header|Axe}}== |
||
Axe supports getting the address of a variable using the degree symbol: |
Axe supports getting the address of a variable using the degree symbol: |
||
< |
<syntaxhighlight lang=axe>°A→B |
||
.B now contains the address of A</ |
.B now contains the address of A</syntaxhighlight> |
||
Axe does not support setting the address of a variable directly. However, it does support setting the value of a variable and then dereferencing it: |
Axe does not support setting the address of a variable directly. However, it does support setting the value of a variable and then dereferencing it: |
||
< |
<syntaxhighlight lang=axe>1234→A |
||
1→{A}</ |
1→{A}</syntaxhighlight> |
||
This should usually be avoided because TI-OS does not use virtual memory. Writing to arbitrary memory locations can affect the stability of the operating system. |
This should usually be avoided because TI-OS does not use virtual memory. Writing to arbitrary memory locations can affect the stability of the operating system. |
||
=={{header|BaCon}}== |
=={{header|BaCon}}== |
||
< |
<syntaxhighlight lang=freebasic> |
||
'---get a variable's address |
'---get a variable's address |
||
LOCAL x TYPE long |
LOCAL x TYPE long |
||
PRINT ADDRESS(x) |
PRINT ADDRESS(x) |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|BASIC}}== |
=={{header|BASIC}}== |
||
Many BASICs, especially older flavors like [[QuickBASIC]], lack the ability to set a variable's address (and indeed, they pretty much all lack the ability to work with pointers in any fashion). |
Many BASICs, especially older flavors like [[QuickBASIC]], lack the ability to set a variable's address (and indeed, they pretty much all lack the ability to work with pointers in any fashion). |
||
< |
<syntaxhighlight lang=qbasic>'get a variable's address: |
||
DIM x AS INTEGER, y AS LONG |
DIM x AS INTEGER, y AS LONG |
||
y = VARPTR(x) |
y = VARPTR(x) |
||
Line 443: | Line 443: | ||
DIM z AS INTEGER |
DIM z AS INTEGER |
||
z = PEEK(y) |
z = PEEK(y) |
||
z = z + (PEEK(y) * 256)</ |
z = z + (PEEK(y) * 256)</syntaxhighlight> |
||
=={{header|BBC BASIC}}== |
=={{header|BBC BASIC}}== |
||
The original BBC BASIC doesn't provide an address-of operator, but ''BBC BASIC for Windows'' does: |
The original BBC BASIC doesn't provide an address-of operator, but ''BBC BASIC for Windows'' does: |
||
< |
<syntaxhighlight lang=bbcbasic>REM get a variable's address: |
||
y% = ^x% |
y% = ^x% |
||
REM can't set a variable's address, but can access a given memory location (4 bytes): |
REM can't set a variable's address, but can access a given memory location (4 bytes): |
||
x% = !y%</ |
x% = !y%</syntaxhighlight> |
||
With BBC BASIC on other platforms the address of a variable can be found by calling a short piece of machine code, see [http://beebwiki.mdfs.net/Address_of_a_variable BeebWiki]. |
With BBC BASIC on other platforms the address of a variable can be found by calling a short piece of machine code, see [http://beebwiki.mdfs.net/Address_of_a_variable BeebWiki]. |
||
Line 460: | Line 460: | ||
=== Get the address === |
=== Get the address === |
||
Note that <code>void*</code> is a "pure" address which doesn't carry the type information anymore. If you need the type information (e.g. to recover the variable itself in a type safe manner), use a pointer to the appropriate type instead; in this case <code>int*</code>. |
Note that <code>void*</code> is a "pure" address which doesn't carry the type information anymore. If you need the type information (e.g. to recover the variable itself in a type safe manner), use a pointer to the appropriate type instead; in this case <code>int*</code>. |
||
< |
<syntaxhighlight lang=cpp>int i; |
||
void* address_of_i = &i;</ |
void* address_of_i = &i;</syntaxhighlight> |
||
'''C++ only:''' C++ allows overloading the <code>&</code> operator. To bypass this, for example in generic code, use the library function <code>addressof</code>: |
'''C++ only:''' C++ allows overloading the <code>&</code> operator. To bypass this, for example in generic code, use the library function <code>addressof</code>: |
||
< |
<syntaxhighlight lang=cpp>#include <memory> |
||
int i; |
int i; |
||
auto address_of_i = std::addressof(i);</ |
auto address_of_i = std::addressof(i);</syntaxhighlight> |
||
=== Set the address === |
=== Set the address === |
||
While C++ doesn't directly support putting a variable at a given address, the same effect can be achieved by creating a reference to that address: |
While C++ doesn't directly support putting a variable at a given address, the same effect can be achieved by creating a reference to that address: |
||
< |
<syntaxhighlight lang=cpp>int& i = *(int*)0xA100;</syntaxhighlight> |
||
If the type of the variable requires initialization, it is necessary to use placement new: |
If the type of the variable requires initialization, it is necessary to use placement new: |
||
< |
<syntaxhighlight lang=cpp>#include <new> |
||
struct S { int i = 0; S() {} }; |
struct S { int i = 0; S() {} }; |
||
auto& s = *new (reinterpret_cast<void*>(0xa100)) S;</ |
auto& s = *new (reinterpret_cast<void*>(0xa100)) S;</syntaxhighlight> |
||
Overlaying of variables is done with anonymous unions; however at global/namespace scope such variables have to be static (i.e. local to the current file): |
Overlaying of variables is done with anonymous unions; however at global/namespace scope such variables have to be static (i.e. local to the current file): |
||
< |
<syntaxhighlight lang=cpp>static union |
||
{ |
{ |
||
int i; |
int i; |
||
int j; |
int j; |
||
};</ |
};</syntaxhighlight> |
||
'''C++ only:''' An alternative (and cleaner) solution is to use references: |
'''C++ only:''' An alternative (and cleaner) solution is to use references: |
||
< |
<syntaxhighlight lang=cpp>int i; |
||
int& j = i;</ |
int& j = i;</syntaxhighlight> |
||
Note that in this case, the variables can be non-static. |
Note that in this case, the variables can be non-static. |
||
If the type of two overlaid variables is not sufficiently similar, then writes to one may not be reflected in reads from the other, even though they have the same address. This is because the optimizer is free to assume that variables of different types do not alias. To read or write a variable as a different type, use <code>memcpy</code>: |
If the type of two overlaid variables is not sufficiently similar, then writes to one may not be reflected in reads from the other, even though they have the same address. This is because the optimizer is free to assume that variables of different types do not alias. To read or write a variable as a different type, use <code>memcpy</code>: |
||
< |
<syntaxhighlight lang=cpp>#include <cstring> |
||
inline float read_as_float(int const& i) { float f; memcpy(&f, &i, sizeof(f)); return f; } |
inline float read_as_float(int const& i) { float f; memcpy(&f, &i, sizeof(f)); return f; } |
||
int i = 0x0a112233; |
int i = 0x0a112233; |
||
float f = read_as_float(i);</ |
float f = read_as_float(i);</syntaxhighlight> |
||
{{omit from|Clojure}} |
{{omit from|Clojure}} |
||
Line 505: | Line 505: | ||
Note that void* is a "pure" address which doesn't carry the type information anymore. If you need the type information (e.g. to recover the variable itself in a type safe manner), use a pointer to the appropriate type instead; in this case int*. |
Note that void* is a "pure" address which doesn't carry the type information anymore. If you need the type information (e.g. to recover the variable itself in a type safe manner), use a pointer to the appropriate type instead; in this case int*. |
||
< |
<syntaxhighlight lang=csharp>unsafe |
||
{ |
{ |
||
int i = 5; |
int i = 5; |
||
void* address_of_i = &i; |
void* address_of_i = &i; |
||
}</ |
}</syntaxhighlight> |
||
=={{header|COBOL}}== |
=={{header|COBOL}}== |
||
Line 515: | Line 515: | ||
===Get Address=== |
===Get Address=== |
||
< |
<syntaxhighlight lang=cobol>data division. |
||
working-storage section. |
working-storage section. |
||
01 ptr usage pointer. |
01 ptr usage pointer. |
||
Line 521: | Line 521: | ||
procedure division. |
procedure division. |
||
set ptr to address of var.</ |
set ptr to address of var.</syntaxhighlight> |
||
===Set Address=== |
===Set Address=== |
||
Sets the address of a variable using the <code>BASED</code> clause. There are other methods, in particular <code>LINKAGE SECTION</code> variables. |
Sets the address of a variable using the <code>BASED</code> clause. There are other methods, in particular <code>LINKAGE SECTION</code> variables. |
||
< |
<syntaxhighlight lang=cobol> |
||
OCOBOL*> Rosetta Code set address example |
OCOBOL*> Rosetta Code set address example |
||
*> tectonics: cobc -x setaddr.cob && ./setaddr |
*> tectonics: cobc -x setaddr.cob && ./setaddr |
||
Line 537: | Line 537: | ||
display var end-display |
display var end-display |
||
goback. |
goback. |
||
end program setaddr.</ |
end program setaddr.</syntaxhighlight> |
||
=={{header|Common Lisp}}== |
=={{header|Common Lisp}}== |
||
Line 547: | Line 547: | ||
Yet, thanks to Lisp macros and lexical closures, we can create reference values which behave like address of places. A tiny module for doing this is found in <strike>[http://paste.lisp.org/display/71952 Lisppaste #71952]</strike> (now it's available [http://www.kylheku.com/cgit/lisp-snippets/tree/refs.lisp here]), required by the following example: |
Yet, thanks to Lisp macros and lexical closures, we can create reference values which behave like address of places. A tiny module for doing this is found in <strike>[http://paste.lisp.org/display/71952 Lisppaste #71952]</strike> (now it's available [http://www.kylheku.com/cgit/lisp-snippets/tree/refs.lisp here]), required by the following example: |
||
< |
<syntaxhighlight lang=lisp>;;; Demonstration of references by swapping two variables using a function rather than a macro |
||
;;; Needs http://paste.lisp.org/display/71952 |
;;; Needs http://paste.lisp.org/display/71952 |
||
(defun swap (ref-left ref-right) |
(defun swap (ref-left ref-right) |
||
Line 562: | Line 562: | ||
;; *y* -> 42 |
;; *y* -> 42 |
||
;; *x* -> 0</ |
;; *x* -> 0</syntaxhighlight> |
||
These references are completely safe to use. There is no way that a place can disappear, leaving a reference dangling, because if a reference is a live object, it prevents the object which contains the referenced place from becoming garbage. Also note that if two references are taken to the same memory location, they are two distinct objects. A function could be provided to test two references for referential equality (do they point to the same object). |
These references are completely safe to use. There is no way that a place can disappear, leaving a reference dangling, because if a reference is a live object, it prevents the object which contains the referenced place from becoming garbage. Also note that if two references are taken to the same memory location, they are two distinct objects. A function could be provided to test two references for referential equality (do they point to the same object). |
||
Line 578: | Line 578: | ||
We wrap this function with a Lisp foreign call which is properly annotated as returning a C pointer to int. When we call this function, we get an object that behaves like a reference to that location. All we need then is a macro which looks like a storage location. |
We wrap this function with a Lisp foreign call which is properly annotated as returning a C pointer to int. When we call this function, we get an object that behaves like a reference to that location. All we need then is a macro which looks like a storage location. |
||
< |
<syntaxhighlight lang=lisp>(use-package :ffi) |
||
(defmacro def-libc-call-out (name &rest args) |
(defmacro def-libc-call-out (name &rest args) |
||
Line 604: | Line 604: | ||
(defsetf get-errno set-errno) |
(defsetf get-errno set-errno) |
||
(define-symbol-macro errno (get-errno)))</ |
(define-symbol-macro errno (get-errno)))</syntaxhighlight> |
||
Test: |
Test: |
||
Line 617: | Line 617: | ||
=={{header|Component Pascal}}== |
=={{header|Component Pascal}}== |
||
BlackBox Component Builder |
BlackBox Component Builder |
||
< |
<syntaxhighlight lang=oberon2> |
||
MODULE AddressVar; |
MODULE AddressVar; |
||
IMPORT SYSTEM,StdLog; |
IMPORT SYSTEM,StdLog; |
||
Line 632: | Line 632: | ||
x := 10; |
x := 10; |
||
END AddressVar. |
END AddressVar. |
||
</syntaxhighlight> |
|||
</lang> |
|||
Execute: ^Q AddressVar.Do<br/> |
Execute: ^Q AddressVar.Do<br/> |
||
{{out}} |
{{out}} |
||
Line 640: | Line 640: | ||
=={{header|Creative Basic}}== |
=={{header|Creative Basic}}== |
||
< |
<syntaxhighlight lang=Creative Basic> |
||
== Get == |
== Get == |
||
Line 713: | Line 713: | ||
#<UINT>pMem = 34234: 'Use bytes 100-103 to store a UINT |
#<UINT>pMem = 34234: 'Use bytes 100-103 to store a UINT |
||
DELETE pMem |
DELETE pMem |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|D}}== |
=={{header|D}}== |
||
Take the address of a variable: |
Take the address of a variable: |
||
< |
<syntaxhighlight lang=d>int i; |
||
int* ip = &i;</ |
int* ip = &i;</syntaxhighlight> |
||
Using a numeric value: |
Using a numeric value: |
||
< |
<syntaxhighlight lang=d>int* ip = cast(int*)0xdeadf00d;</syntaxhighlight> |
||
Locating a "regular" variable at a specific address is not possible. |
Locating a "regular" variable at a specific address is not possible. |
||
Line 728: | Line 728: | ||
The closest thing is passing a dereferenced pointer to a reference parameter. |
The closest thing is passing a dereferenced pointer to a reference parameter. |
||
< |
<syntaxhighlight lang=d>void test(ref int i) { |
||
import std.stdio; |
import std.stdio; |
||
writeln(&i); |
writeln(&i); |
||
Line 735: | Line 735: | ||
void main() { |
void main() { |
||
test(* (cast(int*)0xdeadf00d) ); |
test(* (cast(int*)0xdeadf00d) ); |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Delphi}}== |
=={{header|Delphi}}== |
||
Line 742: | Line 742: | ||
To get the address of any variable, structure, procedure or function use the <tt>@</tt>-operator: |
To get the address of any variable, structure, procedure or function use the <tt>@</tt>-operator: |
||
< |
<syntaxhighlight lang=pascal>var |
||
i: integer; |
i: integer; |
||
p: ^integer; |
p: ^integer; |
||
Line 748: | Line 748: | ||
p := @i; |
p := @i; |
||
writeLn(p^); |
writeLn(p^); |
||
end;</ |
end;</syntaxhighlight> |
||
Note, (untyped) constants do not have an address in Pascal. |
Note, (untyped) constants do not have an address in Pascal. |
||
A variable can be declared as <tt>absolute</tt> i. e.: to reside at a specific address: |
A variable can be declared as <tt>absolute</tt> i. e.: to reside at a specific address: |
||
< |
<syntaxhighlight lang=pascal>var |
||
crtMode: integer absolute $0040; |
crtMode: integer absolute $0040; |
||
str: string[100]; |
str: string[100]; |
||
strLen: byte absolute str; |
strLen: byte absolute str; |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Draco}}== |
=={{header|Draco}}== |
||
< |
<syntaxhighlight lang=draco>/* This code uses a CP/M-specific address to demonstrate fixed locations, |
||
* so it will very likely only work under CP/M */ |
* so it will very likely only work under CP/M */ |
||
proc nonrec main() void: |
proc nonrec main() void: |
||
Line 786: | Line 786: | ||
writeln("var2 address=", pretend(&var2,word):5, " value=", var2:5); |
writeln("var2 address=", pretend(&var2,word):5, " value=", var2:5); |
||
writeln("memtop2 address=", pretend(&memtop2,word):5, " value=", memtop2:5) |
writeln("memtop2 address=", pretend(&memtop2,word):5, " value=", memtop2:5) |
||
corp</ |
corp</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>var address= 276 value= 1234 |
<pre>var address= 276 value= 1234 |
||
Line 800: | Line 800: | ||
ADDR=VARPTR(A%) |
ADDR=VARPTR(A%) |
||
....... |
....... |
||
</syntaxhighlight> |
|||
</lang> |
|||
ADDR contains the value of the address of variable A (from 0 to 65535 because every ERRE module has a 64K address space). ERRE data types is 2 bytes-long for integer, 4 (5 with C-64) for reals and 8 for double-real variables. |
ADDR contains the value of the address of variable A (from 0 to 65535 because every ERRE module has a 64K address space). ERRE data types is 2 bytes-long for integer, 4 (5 with C-64) for reals and 8 for double-real variables. |
||
Using this address you can modify the variable's value without using an assignment statement: |
Using this address you can modify the variable's value without using an assignment statement: |
||
Line 812: | Line 812: | ||
PRINT(A%) ! prints 200 |
PRINT(A%) ! prints 200 |
||
END PROGRAM |
END PROGRAM |
||
</syntaxhighlight> |
|||
</lang> |
|||
Note: With C-64 substitute POKE(ADDR,200) with POKE(ADDR+3,200). |
Note: With C-64 substitute POKE(ADDR,200) with POKE(ADDR+3,200). |
||
Line 868: | Line 868: | ||
=={{header|Fortran}}== |
=={{header|Fortran}}== |
||
{{works with|Fortran|90 and later}} |
{{works with|Fortran|90 and later}} |
||
< |
<syntaxhighlight lang=fortran>program test_loc |
||
implicit none |
implicit none |
||
Line 876: | Line 876: | ||
i = loc(r) |
i = loc(r) |
||
print *, i |
print *, i |
||
end program</ |
end program</syntaxhighlight> |
||
Note: <code>loc</code> is a common extension that is implemented |
Note: <code>loc</code> is a common extension that is implemented |
||
by e.g. the Intel Fortran Compiler, G95 and gfortran. |
by e.g. the Intel Fortran Compiler, G95 and gfortran. |
||
Line 882: | Line 882: | ||
=={{header|FreeBASIC}}== |
=={{header|FreeBASIC}}== |
||
One can get the address of a variable using the @ operator: |
One can get the address of a variable using the @ operator: |
||
< |
<syntaxhighlight lang=freebasic>' FB 1.05.0 Win64 |
||
Dim a As Integer = 3 |
Dim a As Integer = 3 |
||
Dim p As Integer Ptr = @a |
Dim p As Integer Ptr = @a |
||
Print a, p </ |
Print a, p </syntaxhighlight> |
||
To my knowledge, it is not possible to set the address of a variable to a specific address in FB though (as in C/C++) you can do something like this as a workaround: |
To my knowledge, it is not possible to set the address of a variable to a specific address in FB though (as in C/C++) you can do something like this as a workaround: |
||
< |
<syntaxhighlight lang=freebasic>Var p = Cast(Integer Ptr, 1375832) |
||
*p = 42 |
*p = 42 |
||
Print p, *p</ |
Print p, *p</syntaxhighlight> |
||
=={{header|FutureBasic}}== |
=={{header|FutureBasic}}== |
||
< |
<syntaxhighlight lang=futurebasic>window 1 |
||
short i = 575 |
short i = 575 |
||
Line 902: | Line 902: | ||
print @"Value of i = ";peek word(j) |
print @"Value of i = ";peek word(j) |
||
HandleEvents</ |
HandleEvents</syntaxhighlight> |
||
Output: |
Output: |
||
Line 927: | Line 927: | ||
The following demonstrates getting the address of a variable and storing/printing it various ways. |
The following demonstrates getting the address of a variable and storing/printing it various ways. |
||
It also demonstrates accessing an arbitrary memory location (here the known address of a float) as an integer. |
It also demonstrates accessing an arbitrary memory location (here the known address of a float) as an integer. |
||
< |
<syntaxhighlight lang=go>package main |
||
import ( |
import ( |
||
Line 958: | Line 958: | ||
i := (*int32)(unsafe.Pointer(&myVar)) |
i := (*int32)(unsafe.Pointer(&myVar)) |
||
fmt.Printf("value as int32: %#08x\n", *i) |
fmt.Printf("value as int32: %#08x\n", *i) |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
On a 32 bit architecture: |
On a 32 bit architecture: |
||
Line 977: | Line 977: | ||
=={{header|IWBASIC}}== |
=={{header|IWBASIC}}== |
||
< |
<syntaxhighlight lang=IWBASIC> |
||
== Get == |
== Get == |
||
Line 1,007: | Line 1,007: | ||
#<UINT>pMem = 34234: 'Use bytes 100-103 to store a UINT |
#<UINT>pMem = 34234: 'Use bytes 100-103 to store a UINT |
||
DELETE pMem |
DELETE pMem |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|J}}== |
=={{header|J}}== |
||
Line 1,015: | Line 1,015: | ||
<lang> var =: 52 NB. Any variable (including data, functions, operators etc) |
<lang> var =: 52 NB. Any variable (including data, functions, operators etc) |
||
var_addr =: 15!:6<'var' NB. Get address |
var_addr =: 15!:6<'var' NB. Get address |
||
new_var =: 15!:7 var_addr NB. Set address</ |
new_var =: 15!:7 var_addr NB. Set address</syntaxhighlight> |
||
=={{header|Java}}== |
=={{header|Java}}== |
||
Line 1,027: | Line 1,027: | ||
Julia has both mutable and immutable objects. Immutable objects are values, such as constants, bit-based values such as numeric 3, or immutable structs. Immutable objects may not have a single set location in memory, but instead might in some cases be created on demand by the compiled code. Mutable objects such as typical arrays and mutable structs, on the other hand, have addresses on the Julia heap that can be found with specific base Julia functions which use the <code>Ptr</code> type. |
Julia has both mutable and immutable objects. Immutable objects are values, such as constants, bit-based values such as numeric 3, or immutable structs. Immutable objects may not have a single set location in memory, but instead might in some cases be created on demand by the compiled code. Mutable objects such as typical arrays and mutable structs, on the other hand, have addresses on the Julia heap that can be found with specific base Julia functions which use the <code>Ptr</code> type. |
||
To get the memory address of a Julia object, one can use <code>pointer_from_objref(object)</code>, and the reverse is accomplished by <code>unsafe_pointer_to_objref(ptr)</code>: < |
To get the memory address of a Julia object, one can use <code>pointer_from_objref(object)</code>, and the reverse is accomplished by <code>unsafe_pointer_to_objref(ptr)</code>: <syntaxhighlight lang=julia>julia> x = [1, 2, 3] |
||
julia> ptr = pointer_from_objref(x) |
julia> ptr = pointer_from_objref(x) |
||
Ptr{Void} @0x000000010282e4a0 |
Ptr{Void} @0x000000010282e4a0 |
||
Line 1,034: | Line 1,034: | ||
1 |
1 |
||
2 |
2 |
||
3</ |
3</syntaxhighlight> The latter is "unsafe" because it only works if <code>ptr</code> refers to a valid heap-allocated "boxed" Julia object, which can only be safely allocated by Julia itself. |
||
<p>Another common use of pointers is for arrays of values, which are typically passed in low-level C-like libraries via pointers to contiguous sets of values in memory. This is accomplished in Julia by the <code>pointer(A)</code> function, which returns a pointer to the data stored in a high-level Julia array <code>A</code>. Given a pointer <code>p</code> to values of a given type, the <code>i</code>-th value (numbered starting at 1 for the value pointed to by <code>p</code>) can be read or written by the low-level <code>unsafe_load(p, i)</code> and <code>unsafe_store!(p, val, i)</code> functions, or it can be converted back to a high-level Julia array type by the <code>pointer_to_array(p, dimensions)</code> function:< |
<p>Another common use of pointers is for arrays of values, which are typically passed in low-level C-like libraries via pointers to contiguous sets of values in memory. This is accomplished in Julia by the <code>pointer(A)</code> function, which returns a pointer to the data stored in a high-level Julia array <code>A</code>. Given a pointer <code>p</code> to values of a given type, the <code>i</code>-th value (numbered starting at 1 for the value pointed to by <code>p</code>) can be read or written by the low-level <code>unsafe_load(p, i)</code> and <code>unsafe_store!(p, val, i)</code> functions, or it can be converted back to a high-level Julia array type by the <code>pointer_to_array(p, dimensions)</code> function:<syntaxhighlight lang=julia>julia> A = [1, 2.3, 4] |
||
3-element Array{Float64,1}: |
3-element Array{Float64,1}: |
||
1.0 |
1.0 |
||
Line 1,059: | Line 1,059: | ||
1.0 |
1.0 |
||
2.3 |
2.3 |
||
3.14149</ |
3.14149</syntaxhighlight> |
||
Finally, an arbitrary integer can be converted to a pointer type with <code>convert</code>, which allows an arbitrary address to be converted into and viewed as an array of an arbitrary type and read or written (although this can easily result in a crash if an invalid address is used). In the following example, we create a "new" length-two array <code>B</code> at an address offset by 8 bytes from the address of the data in <code>A</code> above, which will make it point to the second element of <code>A</code>:< |
Finally, an arbitrary integer can be converted to a pointer type with <code>convert</code>, which allows an arbitrary address to be converted into and viewed as an array of an arbitrary type and read or written (although this can easily result in a crash if an invalid address is used). In the following example, we create a "new" length-two array <code>B</code> at an address offset by 8 bytes from the address of the data in <code>A</code> above, which will make it point to the second element of <code>A</code>:<syntaxhighlight lang=julia>julia> |
||
julia> q = convert(Ptr{Float64}, 0x0000000113f70d68) |
julia> q = convert(Ptr{Float64}, 0x0000000113f70d68) |
||
Ptr{Float64} @0x0000000113f70d68 |
Ptr{Float64} @0x0000000113f70d68 |
||
Line 1,068: | Line 1,068: | ||
2-element Array{Float64,1}: |
2-element Array{Float64,1}: |
||
2.3 |
2.3 |
||
3.14149</ |
3.14149</syntaxhighlight> |
||
{{omit from|K}} |
{{omit from|K}} |
||
Line 1,077: | Line 1,077: | ||
However, Kotlin/Native which is currently (January 2018) available as a pre-release version does support pointers to enable it to interoperate with C code. The following program shows how to obtain the address of a variable which has been allocated on the native heap. It does not appear to be possible to allocate a variable at a particular address. |
However, Kotlin/Native which is currently (January 2018) available as a pre-release version does support pointers to enable it to interoperate with C code. The following program shows how to obtain the address of a variable which has been allocated on the native heap. It does not appear to be possible to allocate a variable at a particular address. |
||
{{works with|Ubuntu|14.04}} |
{{works with|Ubuntu|14.04}} |
||
< |
<syntaxhighlight lang=scala>// Kotlin Native v0.5 |
||
import kotlinx.cinterop.* |
import kotlinx.cinterop.* |
||
Line 1,086: | Line 1,086: | ||
with(intVar) { println("Value is $value, address is $rawPtr") } |
with(intVar) { println("Value is $value, address is $rawPtr") } |
||
nativeHeap.free(intVar) |
nativeHeap.free(intVar) |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,098: | Line 1,098: | ||
Users are not supposed to access these addresses. During the post-processing phase the addresses which have not been "consumed" by the evaluation are automatically evaluated to show the related values in a convenient way. For instance: |
Users are not supposed to access these addresses. During the post-processing phase the addresses which have not been "consumed" by the evaluation are automatically evaluated to show the related values in a convenient way. For instance: |
||
< |
<syntaxhighlight lang=Scheme> |
||
1) lambdas |
1) lambdas |
||
Line 1,123: | Line 1,123: | ||
-> _QUOT_124 // as replaced and protected before post-processing |
-> _QUOT_124 // as replaced and protected before post-processing |
||
-> {+ 1 2} // as displayed after post-processing |
-> {+ 1 2} // as displayed after post-processing |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Lua}}== |
=={{header|Lua}}== |
||
Pure/native Lua does not support true pointer operations. Memory management is automatic, and garbage-collected, so at best you can hold a temporary reference to the allocated memory. However the "virtual address" of complex types is discoverable (and is in fact how the internals deal with assignment, equality testing, etc), and userdata types typically reveal an actual physical address. |
Pure/native Lua does not support true pointer operations. Memory management is automatic, and garbage-collected, so at best you can hold a temporary reference to the allocated memory. However the "virtual address" of complex types is discoverable (and is in fact how the internals deal with assignment, equality testing, etc), and userdata types typically reveal an actual physical address. |
||
< |
<syntaxhighlight lang=lua>t = {} |
||
print(t) |
print(t) |
||
f = function() end |
f = function() end |
||
Line 1,136: | Line 1,136: | ||
print(u) |
print(u) |
||
print(_G, _ENV) -- global/local environments (are same here) |
print(_G, _ENV) -- global/local environments (are same here) |
||
print(string.format("%p %p %p", print, string, string.format)) -- themselves formatted as pointers</ |
print(string.format("%p %p %p", print, string, string.format)) -- themselves formatted as pointers</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>table: 00000000001d93b0 |
<pre>table: 00000000001d93b0 |
||
Line 1,148: | Line 1,148: | ||
To obtain the address of any expression in Maple, use the builtin function <code>addressof</code>. |
To obtain the address of any expression in Maple, use the builtin function <code>addressof</code>. |
||
< |
<syntaxhighlight lang=Maple>> addressof( x ); |
||
18446884674469911422</ |
18446884674469911422</syntaxhighlight>The inverse operation is <code>pointto</code>:<syntaxhighlight lang=Maple> |
||
> pointto( 18446884674469911422 ); |
> pointto( 18446884674469911422 ); |
||
x</ |
x</syntaxhighlight>This works for any expression, not just variables:<syntaxhighlight lang=Maple>> addressof( sin( x )^2 + cos( x )^2 ); |
||
18446884674469972158 |
18446884674469972158 |
||
> pointto( 18446884674469972158 ); |
> pointto( 18446884674469972158 ); |
||
2 2 |
2 2 |
||
sin(x) + cos(x)</ |
sin(x) + cos(x)</syntaxhighlight> |
||
=={{header|Modula-2}}== |
=={{header|Modula-2}}== |
||
===Get Address=== |
===Get Address=== |
||
< |
<syntaxhighlight lang=modula2>MODULE GetAddress; |
||
FROM SYSTEM IMPORT ADR; |
FROM SYSTEM IMPORT ADR; |
||
Line 1,171: | Line 1,171: | ||
WriteInt(adr, 0); |
WriteInt(adr, 0); |
||
WriteLn; |
WriteLn; |
||
END GetAddress.</ |
END GetAddress.</syntaxhighlight> |
||
===Set Address=== |
===Set Address=== |
||
< |
<syntaxhighlight lang=modula2>MODULE SetAddress; |
||
CONST adress = 134664460; |
CONST adress = 134664460; |
||
Line 1,182: | Line 1,182: | ||
BEGIN |
BEGIN |
||
(*do nothing*) |
(*do nothing*) |
||
END SetAddress.</ |
END SetAddress.</syntaxhighlight> |
||
=={{header|Nanoquery}}== |
=={{header|Nanoquery}}== |
||
===Get Address=== |
===Get Address=== |
||
< |
<syntaxhighlight lang=nanoquery>import native |
||
a = 5 |
a = 5 |
||
println format("0x%08x", native.address(a))</ |
println format("0x%08x", native.address(a))</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>0xc46be580</pre> |
<pre>0xc46be580</pre> |
||
Line 1,196: | Line 1,196: | ||
===Set Address=== |
===Set Address=== |
||
We cannot directly modify the address of a variable that has already be created, but we can create a pointer and move it to point at a different address. |
We cannot directly modify the address of a variable that has already be created, but we can create a pointer and move it to point at a different address. |
||
< |
<syntaxhighlight lang=nanoquery>import native |
||
a = 123 |
a = 123 |
||
Line 1,205: | Line 1,205: | ||
ptr = native.address(b) |
ptr = native.address(b) |
||
println native.object(ptr)</ |
println native.object(ptr)</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>123 |
<pre>123 |
||
Line 1,212: | Line 1,212: | ||
=={{header|NewLISP}}== |
=={{header|NewLISP}}== |
||
===Get Address=== |
===Get Address=== |
||
< |
<syntaxhighlight lang=NewLISP> |
||
(set 'a '(1 2 3)) |
(set 'a '(1 2 3)) |
||
(address a) |
(address a) |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Nim}}== |
=={{header|Nim}}== |
||
< |
<syntaxhighlight lang=nim>var x = 12 |
||
var xptr = addr(x) # Get address of variable |
var xptr = addr(x) # Get address of variable |
||
echo cast[int](xptr) # and print it |
echo cast[int](xptr) # and print it |
||
xptr = cast[ptr int](0xFFFE) # Set the address</ |
xptr = cast[ptr int](0xFFFE) # Set the address</syntaxhighlight> |
||
=={{header|Oberon-2}}== |
=={{header|Oberon-2}}== |
||
Line 1,248: | Line 1,248: | ||
To get the address, we re-interpret the boxed value as an integer; however, this will get the address divided by 2, since the integer only uses the upper 31 (or 63) bits. Therefore, we need to shift this number left by one to get the real address. However, <code>int</code> cannot hold all the bits of the address, so if we shift we will lose a bit, so we use the <code>nativeint</code> type to represent it instead: |
To get the address, we re-interpret the boxed value as an integer; however, this will get the address divided by 2, since the integer only uses the upper 31 (or 63) bits. Therefore, we need to shift this number left by one to get the real address. However, <code>int</code> cannot hold all the bits of the address, so if we shift we will lose a bit, so we use the <code>nativeint</code> type to represent it instead: |
||
< |
<syntaxhighlight lang=ocaml>let address_of (x:'a) : nativeint = |
||
if Obj.is_block (Obj.repr x) then |
if Obj.is_block (Obj.repr x) then |
||
Nativeint.shift_left (Nativeint.of_int (Obj.magic x)) 1 (* magic *) |
Nativeint.shift_left (Nativeint.of_int (Obj.magic x)) 1 (* magic *) |
||
Line 1,260: | Line 1,260: | ||
Printf.printf "%nx\n" (address_of b);; |
Printf.printf "%nx\n" (address_of b);; |
||
let c = 17 in |
let c = 17 in |
||
Printf.printf "%nx\n" (address_of c);; (* error, because int is unboxed *)</ |
Printf.printf "%nx\n" (address_of c);; (* error, because int is unboxed *)</syntaxhighlight> |
||
=={{header|Oforth}}== |
=={{header|Oforth}}== |
||
Line 1,270: | Line 1,270: | ||
For instance, here, after creating and setting a variable A, we store the corresponding word into a variable B : |
For instance, here, after creating and setting a variable A, we store the corresponding word into a variable B : |
||
< |
<syntaxhighlight lang=Oforth>tvar: A |
||
10 to A |
10 to A |
||
Line 1,283: | Line 1,283: | ||
[1] (Integer) 12 |
[1] (Integer) 12 |
||
[2] (Variable) #A |
[2] (Variable) #A |
||
>ok</ |
>ok</syntaxhighlight> |
||
=={{header|Ol}}== |
=={{header|Ol}}== |
||
Line 1,311: | Line 1,311: | ||
=={{header|Panoramic}}== |
=={{header|Panoramic}}== |
||
< |
<syntaxhighlight lang=Panoramic> |
||
== Get == |
== Get == |
||
Line 1,355: | Line 1,355: | ||
''Note:'' An attempt to poke a real or an integer (Panoramic's only numeric types) value of less than 0 or of more than |
''Note:'' An attempt to poke a real or an integer (Panoramic's only numeric types) value of less than 0 or of more than |
||
255 will cause an error. |
255 will cause an error. |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|PARI/GP}}== |
=={{header|PARI/GP}}== |
||
In GP you can sent the address to built-in commands like issquare |
In GP you can sent the address to built-in commands like issquare |
||
<lang |
<syntaxhighlight lang=parigp>issquare(n, &m)</syntaxhighlight> |
||
but you cannot directly compute with it. You can view the address of a variable and other debugging information with the |
but you cannot directly compute with it. You can view the address of a variable and other debugging information with the |
||
<pre>\x</pre> |
<pre>\x</pre> |
||
Line 1,371: | Line 1,371: | ||
=={{header|Perl}}== |
=={{header|Perl}}== |
||
To get the address, get the reference to a variable, and either stringify it, or use Scalar::Util's refaddr() to get just the address. Also see Devel::Peek. |
To get the address, get the reference to a variable, and either stringify it, or use Scalar::Util's refaddr() to get just the address. Also see Devel::Peek. |
||
< |
<syntaxhighlight lang=perl>use Scalar::Util qw(refaddr); |
||
print refaddr(\my $v), "\n"; # 140502490125712</ |
print refaddr(\my $v), "\n"; # 140502490125712</syntaxhighlight> |
||
Alternatively, the address (in hexadecimal) can be directly obtained with <code>printf</code>: |
Alternatively, the address (in hexadecimal) can be directly obtained with <code>printf</code>: |
||
< |
<syntaxhighlight lang=perl>printf "%p", $v; # 7fc949039590</syntaxhighlight> |
||
Use Devel::Pointer::PP if you want to dereference a certain address in memory. |
Use Devel::Pointer::PP if you want to dereference a certain address in memory. |
||
Line 1,380: | Line 1,380: | ||
Simple reference (address) manipulation. |
Simple reference (address) manipulation. |
||
< |
<syntaxhighlight lang=perl>my $a = 12; |
||
my $b = \$a; # get reference |
my $b = \$a; # get reference |
||
$$b = $$b + 30; # access referenced value |
$$b = $$b + 30; # access referenced value |
||
print $a; # prints 42</ |
print $a; # prints 42</syntaxhighlight> |
||
Example how to make variable overlay. |
Example how to make variable overlay. |
||
< |
<syntaxhighlight lang=perl>my $a = 12; |
||
our $b; # you can overlay only global variables (this line is only for strictness) |
our $b; # you can overlay only global variables (this line is only for strictness) |
||
*b = \$a; |
*b = \$a; |
||
print $b; # prints 12 |
print $b; # prints 12 |
||
$b++; |
$b++; |
||
print $a; # prints 13</ |
print $a; # prints 13</syntaxhighlight> |
||
=={{header|Phix}}== |
=={{header|Phix}}== |
||
Line 1,407: | Line 1,407: | ||
compiler only omits the appropriate binary for the currently selected target architecture. |
compiler only omits the appropriate binary for the currently selected target architecture. |
||
You can also use allocate/free with peek/poke to obtain similar effects. |
You can also use allocate/free with peek/poke to obtain similar effects. |
||
<!--< |
<!--<syntaxhighlight lang=Phix>--> |
||
<span style="color: #008080;">procedure</span> <span style="color: #000000;">address</span><span style="color: #0000FF;">()</span> |
<span style="color: #008080;">procedure</span> <span style="color: #000000;">address</span><span style="color: #0000FF;">()</span> |
||
<span style="color: #004080;">object</span> <span style="color: #000000;">V</span> |
<span style="color: #004080;">object</span> <span style="color: #000000;">V</span> |
||
Line 1,432: | Line 1,432: | ||
<span style="color: #000000;">address</span><span style="color: #0000FF;">()</span> |
<span style="color: #000000;">address</span><span style="color: #0000FF;">()</span> |
||
<!--</ |
<!--</syntaxhighlight>--> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 1,446: | Line 1,446: | ||
it is a negative number, and for cons pairs a positive number. The same function |
it is a negative number, and for cons pairs a positive number. The same function |
||
'adr' can then be used to convert that pointer back to the original object. |
'adr' can then be used to convert that pointer back to the original object. |
||
< |
<syntaxhighlight lang=PicoLisp>: (setq X 7) |
||
-> 7 |
-> 7 |
||
Line 1,459: | Line 1,459: | ||
: X |
: X |
||
-> (a b c)</ |
-> (a b c)</syntaxhighlight> |
||
=={{header|PL/I}}== |
=={{header|PL/I}}== |
||
< |
<syntaxhighlight lang=PL/I> |
||
declare addr builtin; /* retrieve address of a variable */ |
declare addr builtin; /* retrieve address of a variable */ |
||
declare ptradd builtin; /* pointer addition */ |
declare ptradd builtin; /* pointer addition */ |
||
Line 1,497: | Line 1,497: | ||
end; |
end; |
||
end; |
end; |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|PL/M}}== |
=={{header|PL/M}}== |
||
< |
<syntaxhighlight lang=pli>100H: |
||
/* THERE IS NO STANDARD LIBRARY |
/* THERE IS NO STANDARD LIBRARY |
||
THIS DEFINES SOME BASIC I/O USING CP/M */ |
THIS DEFINES SOME BASIC I/O USING CP/M */ |
||
Line 1,578: | Line 1,578: | ||
OF THE STRINGS IN THE 'PRINT' CALLS */ |
OF THE STRINGS IN THE 'PRINT' CALLS */ |
||
CALL EXIT; |
CALL EXIT; |
||
EOF</ |
EOF</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>FOO IS 0F00 AND ITS ADDRESS IS 03FA |
<pre>FOO IS 0F00 AND ITS ADDRESS IS 03FA |
||
Line 1,588: | Line 1,588: | ||
=={{header|PowerBASIC}}== |
=={{header|PowerBASIC}}== |
||
< |
<syntaxhighlight lang=powerbasic>'get a variable's address: |
||
DIM x AS INTEGER, y AS LONG |
DIM x AS INTEGER, y AS LONG |
||
y = VARPTR(x) |
y = VARPTR(x) |
||
Line 1,605: | Line 1,605: | ||
'*can* set the address of an array |
'*can* set the address of an array |
||
DIM zzz(1) AS BYTE AT y |
DIM zzz(1) AS BYTE AT y |
||
'zzz(0) = low byte of x, zzz(1) = high byte of x</ |
'zzz(0) = low byte of x, zzz(1) = high byte of x</syntaxhighlight> |
||
=={{header|PureBasic}}== |
=={{header|PureBasic}}== |
||
Get the address of a variable using the '@' operator. |
Get the address of a variable using the '@' operator. |
||
< |
<syntaxhighlight lang=PureBasic>a.i = 5 |
||
MessageRequester("Address",Str(@a))</ |
MessageRequester("Address",Str(@a))</syntaxhighlight> |
||
Set the address of a structured pointer. The pointer can be dereferenced to interact with it's data. Ensure that there is access to the memory address that is assigned to the pointer (i.e. part of allocated memory). |
Set the address of a structured pointer. The pointer can be dereferenced to interact with it's data. Ensure that there is access to the memory address that is assigned to the pointer (i.e. part of allocated memory). |
||
< |
<syntaxhighlight lang=PureBasic>a.i = 5 |
||
*b.Integer = @a ;set *b equal to the address of variable a |
*b.Integer = @a ;set *b equal to the address of variable a |
||
*c.Integer = $A100 ;set *c to point at memory location $A100 (in hex) |
*c.Integer = $A100 ;set *c to point at memory location $A100 (in hex) |
||
Line 1,620: | Line 1,620: | ||
MessageRequester("Address",Str(*b)) ;display the address being pointed at by *b |
MessageRequester("Address",Str(*b)) ;display the address being pointed at by *b |
||
MessageRequester("Value",Str(*b\i)) ;de-reference the pointer *b to display the data being pointed at</ |
MessageRequester("Value",Str(*b\i)) ;de-reference the pointer *b to display the data being pointed at</syntaxhighlight> |
||
=={{header|Python}}== |
=={{header|Python}}== |
||
Line 1,628: | Line 1,628: | ||
The Python ''id()'' function returns a unique ID for any object. This just happens to be implemented as the base address of the object in C Python[http://docs.python.org/library/functions.html#id]; but that is not guaranteed by the semantics of the language and should not be considered a standard, nor used as such. But for comparison purposes the ID can be used as an address, since different extant objects will have different IDs. |
The Python ''id()'' function returns a unique ID for any object. This just happens to be implemented as the base address of the object in C Python[http://docs.python.org/library/functions.html#id]; but that is not guaranteed by the semantics of the language and should not be considered a standard, nor used as such. But for comparison purposes the ID can be used as an address, since different extant objects will have different IDs. |
||
< |
<syntaxhighlight lang=python>foo = object() # Create (instantiate) an empty object |
||
address = id(foo)</ |
address = id(foo)</syntaxhighlight> |
||
In addition some folks have written binary Python modules which implement "peek" and "poke" operations, but these are non-standard. |
In addition some folks have written binary Python modules which implement "peek" and "poke" operations, but these are non-standard. |
||
Line 1,635: | Line 1,635: | ||
=={{header|QB64}}== |
=={{header|QB64}}== |
||
< |
<syntaxhighlight lang=QB64> |
||
' Adapted from QB64wiki example a demo of _MEM type data and _MEM functions |
' Adapted from QB64wiki example a demo of _MEM type data and _MEM functions |
||
Type points |
Type points |
||
Line 1,676: | Line 1,676: | ||
_MemPut m(3), m(3).OFFSET, Saved.z |
_MemPut m(3), m(3).OFFSET, Saved.z |
||
End Sub |
End Sub |
||
</syntaxhighlight> |
|||
</lang> |
|||
< |
<syntaxhighlight lang=QB64> |
||
' Full demonstration of being together Qbasic and QB64 methods for accessing and modifying memory directly |
' Full demonstration of being together Qbasic and QB64 methods for accessing and modifying memory directly |
||
Dim A As Integer, B As String, C(1 To 4) As Double |
Dim A As Integer, B As String, C(1 To 4) As Double |
||
Line 1,729: | Line 1,729: | ||
_MemFree M |
_MemFree M |
||
End |
End |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|R}}== |
=={{header|R}}== |
||
Line 1,735: | Line 1,735: | ||
===With the library pryr=== |
===With the library pryr=== |
||
< |
<syntaxhighlight lang=rsplus> |
||
x <- 5 |
x <- 5 |
||
y <- x |
y <- x |
||
Line 1,745: | Line 1,745: | ||
pryr::address(x) |
pryr::address(x) |
||
pryr::address(y) |
pryr::address(y) |
||
</syntaxhighlight> |
|||
</lang> |
|||
===Without any libraries=== |
===Without any libraries=== |
||
< |
<syntaxhighlight lang=rsplus> |
||
address <- function(obj) { |
address <- function(obj) { |
||
paste0("0x", substring(sub(" .*$","",capture.output(.Internal(inspect(obj)))),2)) |
paste0("0x", substring(sub(" .*$","",capture.output(.Internal(inspect(obj)))),2)) |
||
Line 1,761: | Line 1,761: | ||
address(x) |
address(x) |
||
address(y) |
address(y) |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
Line 1,772: | Line 1,772: | ||
=={{header|Racket}}== |
=={{header|Racket}}== |
||
< |
<syntaxhighlight lang=racket>#lang racket |
||
(require ffi/unsafe) |
(require ffi/unsafe) |
||
(define (madness v) ; i'm so sorry |
(define (madness v) ; i'm so sorry |
||
(cast v _racket _gcpointer))</ |
(cast v _racket _gcpointer))</syntaxhighlight> |
||
To test that it is doing "sane" things, you can retrieve the value of the C short located at the pointer produced. Racket objects start with a 2-byte tag indicating their type. These calls should all produce fairly small numbers: the Racket source I'm looking at uses only the first 259 tag values. Small fixnums are stored directly in tagged pointers, so attempting this dereferencing on the pointer madness gives you from a fixnum will most likely segfault your process. |
To test that it is doing "sane" things, you can retrieve the value of the C short located at the pointer produced. Racket objects start with a 2-byte tag indicating their type. These calls should all produce fairly small numbers: the Racket source I'm looking at uses only the first 259 tag values. Small fixnums are stored directly in tagged pointers, so attempting this dereferencing on the pointer madness gives you from a fixnum will most likely segfault your process. |
||
< |
<syntaxhighlight lang=racket> |
||
(ptr-ref (madness +) _short) |
(ptr-ref (madness +) _short) |
||
(ptr-ref (madness (/ 4 3)) _short) |
(ptr-ref (madness (/ 4 3)) _short) |
||
Line 1,788: | Line 1,788: | ||
(ptr-ref (madness #\a) _short) |
(ptr-ref (madness #\a) _short) |
||
(ptr-ref (madness 'foo) _short) |
(ptr-ref (madness 'foo) _short) |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Raku}}== |
=={{header|Raku}}== |
||
(formerly Perl 6) |
(formerly Perl 6) |
||
{{works with|Rakudo|2015.12}} |
{{works with|Rakudo|2015.12}} |
||
< |
<syntaxhighlight lang=perl6>my $x; |
||
say $x.WHERE; |
say $x.WHERE; |
||
Line 1,802: | Line 1,802: | ||
$x = 42; |
$x = 42; |
||
say $y; # 42 |
say $y; # 42 |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre>7857931379550584425</pre> |
<pre>7857931379550584425</pre> |
||
Line 1,808: | Line 1,808: | ||
=={{header|RapidQ}}== |
=={{header|RapidQ}}== |
||
<syntaxhighlight lang=vb> |
|||
<lang vb> |
|||
Dim TheAddress as long |
Dim TheAddress as long |
||
Dim SecVar as byte |
Dim SecVar as byte |
||
Line 1,828: | Line 1,828: | ||
'SecVar is now also = 102 |
'SecVar is now also = 102 |
||
showmessage "SecVar = " + str$(SecVar) |
showmessage "SecVar = " + str$(SecVar) |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Retro}}== |
=={{header|Retro}}== |
||
Line 1,834: | Line 1,834: | ||
===Get The Address=== |
===Get The Address=== |
||
< |
<syntaxhighlight lang=Retro>'a var |
||
&a</ |
&a</syntaxhighlight> |
||
===Set The Address=== |
===Set The Address=== |
||
Create variable '''b''' and point it to address '''100''' |
Create variable '''b''' and point it to address '''100''' |
||
< |
<syntaxhighlight lang=Retro>'b var |
||
#100 @Dictionary d:xt store</ |
#100 @Dictionary d:xt store</syntaxhighlight> |
||
===Byte Addressing=== |
===Byte Addressing=== |
||
Line 1,848: | Line 1,848: | ||
To read the value at byte address 100: |
To read the value at byte address 100: |
||
< |
<syntaxhighlight lang=Retro>'example/ByteAddressing.forth include |
||
#100 b:fetch</ |
#100 b:fetch</syntaxhighlight> |
||
Or to alter the value at byte address 100: |
Or to alter the value at byte address 100: |
||
<lang |
<syntaxhighlight lang=Retro>$e #100 b:store</syntaxhighlight> |
||
=={{header|REXX}}== |
=={{header|REXX}}== |
||
Line 1,861: | Line 1,861: | ||
<br>the state of any variable (defined or not defined, its value, length of the variable's value). |
<br>the state of any variable (defined or not defined, its value, length of the variable's value). |
||
<br><br>It is possible to use the BIF (shown below) (at least, in the original REXX) |
<br><br>It is possible to use the BIF (shown below) (at least, in the original REXX) |
||
< |
<syntaxhighlight lang=rexx>zzz = storage(xxx)</syntaxhighlight> |
||
(but only in '''some''' REXX interpreters) to access the internal REXX pool of variables, but it |
(but only in '''some''' REXX interpreters) to access the internal REXX pool of variables, but it |
||
<br>would depend on the (internal) REXX internal structure(s) and almost likely be not portable nor |
<br>would depend on the (internal) REXX internal structure(s) and almost likely be not portable nor |
||
Line 1,878: | Line 1,878: | ||
For classes that do not override the <code>to_s</code> method, the <code>to_s</code> method also shows the address. |
For classes that do not override the <code>to_s</code> method, the <code>to_s</code> method also shows the address. |
||
< |
<syntaxhighlight lang=ruby>>foo = Object.new # => #<Object:0x10ae32000> |
||
>id = foo.object_id # => 2238812160 |
>id = foo.object_id # => 2238812160 |
||
>"%x" % (id << 1) # => "10ae32000" |
>"%x" % (id << 1) # => "10ae32000" |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Rust}}== |
=={{header|Rust}}== |
||
Line 1,887: | Line 1,887: | ||
It is not possible to change the memory address of an existing variable in Rust directly. However, you could make a copy of the value and then write it to a specific address. |
It is not possible to change the memory address of an existing variable in Rust directly. However, you could make a copy of the value and then write it to a specific address. |
||
< |
<syntaxhighlight lang=rust>let v1 = vec![vec![1,2,3]; 10]; |
||
println!("Original address: {:p}", &v1); |
println!("Original address: {:p}", &v1); |
||
let mut v2; |
let mut v2; |
||
Line 1,897: | Line 1,897: | ||
// scope, which is good since then we'd have a vector of free'd vectors |
// scope, which is good since then we'd have a vector of free'd vectors |
||
unsafe {ptr::write(addr, v1)} |
unsafe {ptr::write(addr, v1)} |
||
println!("New address: {:p}", &v2);</ |
println!("New address: {:p}", &v2);</syntaxhighlight> |
||
Get the memory address of a variable: |
Get the memory address of a variable: |
||
< |
<syntaxhighlight lang=rust>let var = 1; |
||
println!("address of var: {:p}", &var);</ |
println!("address of var: {:p}", &var);</syntaxhighlight> |
||
Get the value at a certain memory address: |
Get the value at a certain memory address: |
||
< |
<syntaxhighlight lang=rust>let address: usize = 0x7ffc8f303130; |
||
unsafe { |
unsafe { |
||
let val = *(address as *const usize); |
let val = *(address as *const usize); |
||
println!("value at {}: {:?}", address, val); |
println!("value at {}: {:?}", address, val); |
||
}</ |
}</syntaxhighlight> |
||
Set the value at a certain memory address: |
Set the value at a certain memory address: |
||
< |
<syntaxhighlight lang=rust>unsafe { |
||
*(0x7ffc8f303130 as *mut usize) = 1; |
*(0x7ffc8f303130 as *mut usize) = 1; |
||
// Note that this invokes undefined behavior if 0x7ffc8f303130 is uninitialized. In that case, std::ptr::write should be used. |
// Note that this invokes undefined behavior if 0x7ffc8f303130 is uninitialized. In that case, std::ptr::write should be used. |
||
std::ptr::write(0x7ffc8f303130 as *mut usize, 1); |
std::ptr::write(0x7ffc8f303130 as *mut usize, 1); |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Scala}}== |
=={{header|Scala}}== |
||
Line 1,921: | Line 1,921: | ||
=={{header|Sidef}}== |
=={{header|Sidef}}== |
||
< |
<syntaxhighlight lang=ruby>var n = 42; |
||
say Sys.refaddr(\n); # prints the address of the variable |
say Sys.refaddr(\n); # prints the address of the variable |
||
say Sys.refaddr(n); # prints the address of the object at which the variable points to</ |
say Sys.refaddr(n); # prints the address of the object at which the variable points to</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 1,936: | Line 1,936: | ||
You asked for it, and here it is: |
You asked for it, and here it is: |
||
{{works with|Smalltalk/X}} |
{{works with|Smalltalk/X}} |
||
< |
<syntaxhighlight lang=smalltalk>|p| |
||
p := Point x:10 y:20. |
p := Point x:10 y:20. |
||
ObjectMemory addressOf:p. |
ObjectMemory addressOf:p. |
||
ObjectMemory collectGarbage. |
ObjectMemory collectGarbage. |
||
ObjectMemory addressOf:p "may return another value"</ |
ObjectMemory addressOf:p "may return another value"</syntaxhighlight> |
||
to deal with non-Smalltalk objects, all Smalltalks provide libraries to pass-in and out parameters to foreign function calls (FFI). The underlying memory block will not be moved by the garbage collector and the address can be passed to external (eg. C, C++, asm) functions. |
to deal with non-Smalltalk objects, all Smalltalks provide libraries to pass-in and out parameters to foreign function calls (FFI). The underlying memory block will not be moved by the garbage collector and the address can be passed to external (eg. C, C++, asm) functions. |
||
For those, we can allocate a block of memory and fiddle around with its "address": |
For those, we can allocate a block of memory and fiddle around with its "address": |
||
{{works with|Smalltalk/X}}{{works with|VisualWorks Smalltalk}} |
{{works with|Smalltalk/X}}{{works with|VisualWorks Smalltalk}} |
||
< |
<syntaxhighlight lang=smalltalk>|ptr| |
||
ptr := ExternalBytes new:10. |
ptr := ExternalBytes new:10. |
||
ptr address. |
ptr address. |
||
ptr byteAt:1 put: 16rFF.</ |
ptr byteAt:1 put: 16rFF.</syntaxhighlight> |
||
However, there are "reference holders", similar to box-objects in scheme/lisp. In Smalltalk these are called "ValueHolder" and are heavily used in UI frameworks. Usually, they are used with the observer pattern as shown in the following example: |
However, there are "reference holders", similar to box-objects in scheme/lisp. In Smalltalk these are called "ValueHolder" and are heavily used in UI frameworks. Usually, they are used with the observer pattern as shown in the following example: |
||
Line 1,954: | Line 1,954: | ||
holder onChangeSend:#someChange to:someone. |
holder onChangeSend:#someChange to:someone. |
||
holder value: 234 |
holder value: 234 |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{omit from|Smart BASIC}} |
{{omit from|Smart BASIC}} |
||
Line 1,962: | Line 1,962: | ||
It's not possible to set the address of a variable, but on can get the address of a variable or a function with the & operator. |
It's not possible to set the address of a variable, but on can get the address of a variable or a function with the & operator. |
||
< |
<syntaxhighlight lang=stata>a = 1 |
||
&a |
&a |
||
Line 1,969: | Line 1,969: | ||
} |
} |
||
&f()</ |
&f()</syntaxhighlight> |
||
=={{header|Swift}}== |
=={{header|Swift}}== |
||
< |
<syntaxhighlight lang=swift> |
||
class MyClass { } |
class MyClass { } |
||
Line 2,002: | Line 2,002: | ||
test() |
test() |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 2,022: | Line 2,022: | ||
<br> |
<br> |
||
{{libheader|critcl}} |
{{libheader|critcl}} |
||
< |
<syntaxhighlight lang=tcl>package require critcl |
||
# This code assumes an ILP32 architecture, like classic x86 or VAX. |
# This code assumes an ILP32 architecture, like classic x86 or VAX. |
||
critcl::cproc peek {int addr} int { |
critcl::cproc peek {int addr} int { |
||
Line 2,042: | Line 2,042: | ||
*u.a = value; |
*u.a = value; |
||
} |
} |
||
package provide poker 1.0</ |
package provide poker 1.0</syntaxhighlight> |
||
Demonstrating: |
Demonstrating: |
||
< |
<syntaxhighlight lang=tcl>package require poker |
||
# Increment a memory location; this will probably crash if you try for real. |
# Increment a memory location; this will probably crash if you try for real. |
||
Line 2,050: | Line 2,050: | ||
# for embedded programming... |
# for embedded programming... |
||
set where 0x12340 |
set where 0x12340 |
||
poke $where [expr {[peek $where] + 1}]</ |
poke $where [expr {[peek $where] + 1}]</syntaxhighlight> |
||
Have great care with this sort of code; the damage you can do by writing to random locations is considerable and being able to read from anywhere could allow information to flow to otherwise unauthorized programs. |
Have great care with this sort of code; the damage you can do by writing to random locations is considerable and being able to read from anywhere could allow information to flow to otherwise unauthorized programs. |
||
Line 2,073: | Line 2,073: | ||
The '''VarPtr''' function allows one to get the address of a variable. There are also functions to peek/poke values at a given address. |
The '''VarPtr''' function allows one to get the address of a variable. There are also functions to peek/poke values at a given address. |
||
< |
<syntaxhighlight lang=vb>Option Explicit |
||
Declare Sub GetMem1 Lib "msvbvm60" (ByVal ptr As Long, ByRef x As Byte) |
Declare Sub GetMem1 Lib "msvbvm60" (ByVal ptr As Long, ByRef x As Byte) |
||
Declare Sub GetMem2 Lib "msvbvm60" (ByVal ptr As Long, ByRef x As Integer) |
Declare Sub GetMem2 Lib "msvbvm60" (ByVal ptr As Long, ByRef x As Integer) |
||
Line 2,096: | Line 2,096: | ||
Call PutMem4(ptr, 87654321) |
Call PutMem4(ptr, 87654321) |
||
Debug.Print a |
Debug.Print a |
||
End Sub</ |
End Sub</syntaxhighlight> |
||
=={{header|Visual Basic .NET}}== |
=={{header|Visual Basic .NET}}== |
||
Line 2,117: | Line 2,117: | ||
=={{header|Wart}}== |
=={{header|Wart}}== |
||
< |
<syntaxhighlight lang=wart>addr.x |
||
=> 27975840</ |
=> 27975840</syntaxhighlight> |
||
<code>addr</code> is guaranteed to provide a stable identifier ''for this session''. The address is just a number like any other and you can perform all the arithmetic you like on it. However, there's no way to dereference an address back into a value, so this is not pointer arithmetic. The primary use of <code>addr</code> is to check if two objects are the same and not just copies, like Common Lisp's <code>eq</code> operator. |
<code>addr</code> is guaranteed to provide a stable identifier ''for this session''. The address is just a number like any other and you can perform all the arithmetic you like on it. However, there's no way to dereference an address back into a value, so this is not pointer arithmetic. The primary use of <code>addr</code> is to check if two objects are the same and not just copies, like Common Lisp's <code>eq</code> operator. |
||
< |
<syntaxhighlight lang=wart>if (addr.x = addr.y) |
||
..</ |
..</syntaxhighlight> |
||
As a result, Wart has only one way to compare values: by default two objects are considered equal if they are structurally isomorphic. (You can override it if you want a different behavior.) |
As a result, Wart has only one way to compare values: by default two objects are considered equal if they are structurally isomorphic. (You can override it if you want a different behavior.) |
||
Line 2,133: | Line 2,133: | ||
You can, of course, assign a variable of one reference type to another which under the hood copies the pointer so that both variables access the same data store. |
You can, of course, assign a variable of one reference type to another which under the hood copies the pointer so that both variables access the same data store. |
||
< |
<syntaxhighlight lang=ecmascript>var a = [1, 2, 3, 4] |
||
var b = a // now 'a' and 'b' both point to the same List data |
var b = a // now 'a' and 'b' both point to the same List data |
||
b[3] = 5 |
b[3] = 5 |
||
Line 2,139: | Line 2,139: | ||
System.print("'a' is %(a)") // the previous change is of course reflected in 'a' as well |
System.print("'a' is %(a)") // the previous change is of course reflected in 'a' as well |
||
var t = Object.same(a, b) // tells you whether 'a' and 'b' refer to the same object in memory |
var t = Object.same(a, b) // tells you whether 'a' and 'b' refer to the same object in memory |
||
System.print("'a' and 'b' are the same object? %(t ? "yes" : "no")")</ |
System.print("'a' and 'b' are the same object? %(t ? "yes" : "no")")</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 2,150: | Line 2,150: | ||
=={{header|X86 Assembly}}== |
=={{header|X86 Assembly}}== |
||
For SVR4 Unix-like style assembler the address of a variable is its symbol. (On some systems the names of C language variables have an extra leading underscore.) |
For SVR4 Unix-like style assembler the address of a variable is its symbol. (On some systems the names of C language variables have an extra leading underscore.) |
||
< |
<syntaxhighlight lang=Assembler> movl my_variable, %eax</syntaxhighlight> |
||
For SVR4 style code destined for a shared library it's necessary to fetch the address from the global offset table to ensure position independent code. That table is found relative to the program counter using the special <code>_GLOBAL_OFFSET_TABLE_</code> (or on some systems extra leading underscore <code>__GLOBAL_OFFSET_TABLE_</code>). The C compiler normally does this in <code>%ebx</code> but for hand-crafted assembler anything equivalent is possible. |
For SVR4 style code destined for a shared library it's necessary to fetch the address from the global offset table to ensure position independent code. That table is found relative to the program counter using the special <code>_GLOBAL_OFFSET_TABLE_</code> (or on some systems extra leading underscore <code>__GLOBAL_OFFSET_TABLE_</code>). The C compiler normally does this in <code>%ebx</code> but for hand-crafted assembler anything equivalent is possible. |
||
< |
<syntaxhighlight lang=Assembler> call eip_to_eax |
||
addl $_GLOBAL_OFFSET_TABLE_, %eax |
addl $_GLOBAL_OFFSET_TABLE_, %eax |
||
movl my_variable@GOT(%eax), %eax |
movl my_variable@GOT(%eax), %eax |
||
Line 2,160: | Line 2,160: | ||
eip_to_eax: |
eip_to_eax: |
||
movl (%esp), %eax |
movl (%esp), %eax |
||
ret</ |
ret</syntaxhighlight> |
||
=={{header|XLISP}}== |
=={{header|XLISP}}== |
||
To get the address in the heap of a variable <code>X</code>, use: |
To get the address in the heap of a variable <code>X</code>, use: |
||
<lang |
<syntaxhighlight lang=lisp>(%ADDRESS-OF X)</syntaxhighlight> |
||
If by "setting the address" we mean compelling the system to store a variable at a particular address of our choosing, then there is no easy way to do that. |
If by "setting the address" we mean compelling the system to store a variable at a particular address of our choosing, then there is no easy way to do that. |
||
Line 2,178: | Line 2,178: | ||
instead of a 32-bit relative address, when used on a 'real' variable. |
instead of a 32-bit relative address, when used on a 'real' variable. |
||
< |
<syntaxhighlight lang=XPL0>include c:\cxpl\codes; |
||
int A, B; |
int A, B; |
||
[B:= addr A; |
[B:= addr A; |
||
Line 2,184: | Line 2,184: | ||
B(0):= $1234ABCD; |
B(0):= $1234ABCD; |
||
HexOut(0, A); CrLf(0); |
HexOut(0, A); CrLf(0); |
||
]</ |
]</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 2,214: | Line 2,214: | ||
===Specifying a Memory Location=== |
===Specifying a Memory Location=== |
||
Only the accumulator <code>A</code> can do this. If you want to store another 8-bit register's contents directly into memory, you'll need to load that register's contents into <code>A</code> first: |
Only the accumulator <code>A</code> can do this. If you want to store another 8-bit register's contents directly into memory, you'll need to load that register's contents into <code>A</code> first: |
||
< |
<syntaxhighlight lang=z80>foo equ &C000 |
||
bar equ &C001 |
bar equ &C001 |
||
ld (foo),a ;store A into memory location &C000 |
ld (foo),a ;store A into memory location &C000 |
||
ld a,b ;copy B to A |
ld a,b ;copy B to A |
||
ld (bar),a ;store "B" into memory location &C001</ |
ld (bar),a ;store "B" into memory location &C001</syntaxhighlight> |
||
===Using BC or DE=== |
===Using BC or DE=== |
||
Only the accumulator <code>A</code> can do this. If you want to store another 8-bit register's contents into the address pointed to by BC or DE, you'll need to load that register's contents into <code>A</code> first: |
Only the accumulator <code>A</code> can do this. If you want to store another 8-bit register's contents into the address pointed to by BC or DE, you'll need to load that register's contents into <code>A</code> first: |
||
< |
<syntaxhighlight lang=z80>foo equ &C000 |
||
bar equ &C001 |
bar equ &C001 |
||
Line 2,229: | Line 2,229: | ||
ld de,bar |
ld de,bar |
||
ld (de),a</ |
ld (de),a</syntaxhighlight> |
||
===Using HL=== |
===Using HL=== |
||
The 8-bit registers <code>A,B,C,D,E</code> can all do this. H and L cannot, unless the value being stored happens to equal that "half" of the memory location. |
The 8-bit registers <code>A,B,C,D,E</code> can all do this. H and L cannot, unless the value being stored happens to equal that "half" of the memory location. |
||
< |
<syntaxhighlight lang=z80>foo equ &C000 |
||
bar equ &C001 |
bar equ &C001 |
||
ld hl,foo |
ld hl,foo |
||
Line 2,241: | Line 2,241: | ||
inc hl |
inc hl |
||
ld (hl),c ;store the contents of C into bar</ |
ld (hl),c ;store the contents of C into bar</syntaxhighlight> |
||
===16-Bit Values into A Specified Memory Location=== |
===16-Bit Values into A Specified Memory Location=== |
||
Storing a 16-Bit value is a little more complicated. The registers <code>BC,DE,HL,IX,IY,SP</code> can all do this, with a specified memory location. The "low byte" of the register (<code>C, E, L, IXL, IYL,</code> and the low byte of <code>SP</code>) are stored at the memory location specified in parentheses, and the "high byte" of the register (<code>B, D, H, IXH, IYH,</code> and the high byte of <code>SP</code>) are stored in the memory location <i>after that</i>. The Game Boy/Sharp LR35902 can only do this with SP, and no other registers. |
Storing a 16-Bit value is a little more complicated. The registers <code>BC,DE,HL,IX,IY,SP</code> can all do this, with a specified memory location. The "low byte" of the register (<code>C, E, L, IXL, IYL,</code> and the low byte of <code>SP</code>) are stored at the memory location specified in parentheses, and the "high byte" of the register (<code>B, D, H, IXH, IYH,</code> and the high byte of <code>SP</code>) are stored in the memory location <i>after that</i>. The Game Boy/Sharp LR35902 can only do this with SP, and no other registers. |
||
< |
<syntaxhighlight lang=z80>foo equ &C000 |
||
bar equ &C001 |
bar equ &C001 |
||
ld (foo),bc ;store C into "foo" and B into "bar"</ |
ld (foo),bc ;store C into "foo" and B into "bar"</syntaxhighlight> |
||
Beware! In this example, the second instruction clobbers part of the first. It's important to be careful when storing 16-bit values into memory. |
Beware! In this example, the second instruction clobbers part of the first. It's important to be careful when storing 16-bit values into memory. |
||
< |
<syntaxhighlight lang=z80>foo equ &C000 |
||
bar equ &C001 |
bar equ &C001 |
||
ld (foo),de ;store E into &C000 and D into &C001 |
ld (foo),de ;store E into &C000 and D into &C001 |
||
ld (bar),bc ;store C into &C001 and B into &C002</ |
ld (bar),bc ;store C into &C001 and B into &C002</syntaxhighlight> |
||
=={{header|Zig}}== |
=={{header|Zig}}== |
||
< |
<syntaxhighlight lang=zig>const std = @import("std"); |
||
pub fn main() !void { |
pub fn main() !void { |
||
Line 2,267: | Line 2,267: | ||
try stdout.print("{x}\n", .{@ptrToInt(address_of_i)}); |
try stdout.print("{x}\n", .{@ptrToInt(address_of_i)}); |
||
}</ |
}</syntaxhighlight> |
||
{{omit from|8th|Impossible to access address of a variable}} |
{{omit from|8th|Impossible to access address of a variable}} |