Create an object at a given address: Difference between revisions
Content deleted Content added
Thundergnat (talk | contribs) m syntax highlighting fixup automation |
|||
Line 23: | Line 23: | ||
Data can be stored, one byte at a time, through the store instructions, for example to store data at $1900: |
Data can be stored, one byte at a time, through the store instructions, for example to store data at $1900: |
||
< |
<syntaxhighlight lang="6502asm"> sta $1900 |
||
stx $1901 |
stx $1901 |
||
sty $1902</ |
sty $1902</syntaxhighlight> |
||
Storage can be indexed through the use of the X or Y registers: |
Storage can be indexed through the use of the X or Y registers: |
||
< |
<syntaxhighlight lang="6502asm"> ldx #54 |
||
.loop sta $1900,X |
.loop sta $1900,X |
||
dex |
dex |
||
bne loop</ |
bne loop</syntaxhighlight> |
||
It can also be stored via indirect indexed addressing (i.e. memory points to an address), using the Y register: |
It can also be stored via indirect indexed addressing (i.e. memory points to an address), using the Y register: |
||
< |
<syntaxhighlight lang="6502asm"> lda #0 |
||
sta $70 |
sta $70 |
||
lda #$20 |
lda #$20 |
||
sta $71 |
sta $71 |
||
ldy #0 |
ldy #0 |
||
sta ($70),Y</ |
sta ($70),Y</syntaxhighlight> |
||
Finally, it can be stored via indexed indirect addressing (i.e. read the address of memory from the table stored at the parameter), using the X register: |
Finally, it can be stored via indexed indirect addressing (i.e. read the address of memory from the table stored at the parameter), using the X register: |
||
< |
<syntaxhighlight lang="6502asm"> lda #0 |
||
sta $70 |
sta $70 |
||
lda #$20 |
lda #$20 |
||
sta $71 |
sta $71 |
||
ldx #0 |
ldx #0 |
||
sta ($70,X)</ |
sta ($70,X)</syntaxhighlight> |
||
It should be noted that on the 6502 processor hardware is normally memory mapped, so this is often used for manipulating hardware. |
It should be noted that on the 6502 processor hardware is normally memory mapped, so this is often used for manipulating hardware. |
||
=={{header|68000 Assembly}}== |
=={{header|68000 Assembly}}== |
||
First, an integer object will be created at address $100000: |
First, an integer object will be created at address $100000: |
||
<lang |
<syntaxhighlight lang="68000devpac">MOVE.L #$12345678,$100000</syntaxhighlight> |
||
Finding the address of a given object isn't actually possible in the same way it would be on [[C]], since anything loaded from an address is just a numeric copy and is not actually related in any way to the "object." The closest way is to label a memory address and load that label as a numeric constant. |
Finding the address of a given object isn't actually possible in the same way it would be on [[C]], since anything loaded from an address is just a numeric copy and is not actually related in any way to the "object." The closest way is to label a memory address and load that label as a numeric constant. |
||
< |
<syntaxhighlight lang="68000devpac">myVariable equ $100000 |
||
MOVE.L #myVariable,D0 |
MOVE.L #myVariable,D0 |
||
JSR printLong ;some unimplemented printing routine.</ |
JSR printLong ;some unimplemented printing routine.</syntaxhighlight> |
||
Creating a new object at that location is as simple as storing a new value there. |
Creating a new object at that location is as simple as storing a new value there. |
||
<lang |
<syntaxhighlight lang="68000devpac">MOVE.L #$FFFFFFFF,myVariable</syntaxhighlight> |
||
=={{header|8086 Assembly}}== |
=={{header|8086 Assembly}}== |
||
This example uses UASM to assemble MS-DOS compatible code. |
This example uses UASM to assemble MS-DOS compatible code. |
||
< |
<syntaxhighlight lang="asm">.model small ;specify memory model to use |
||
.stack 1024 ;set up stack |
.stack 1024 ;set up stack |
||
Line 95: | Line 95: | ||
;get the address of a variable |
;get the address of a variable |
||
mov ax, tempLong_LoWord ;without "word ptr" and brackets, the assembler interprets a label as a constant.</ |
mov ax, tempLong_LoWord ;without "word ptr" and brackets, the assembler interprets a label as a constant.</syntaxhighlight> |
||
=={{header|Action!}}== |
=={{header|Action!}}== |
||
< |
<syntaxhighlight lang="action!">DEFINE FIRST="12345" |
||
DEFINE SECOND="54321" |
DEFINE SECOND="54321" |
||
DEFINE PTR="CARD" |
DEFINE PTR="CARD" |
||
Line 119: | Line 119: | ||
PrintF("Value of base variable: %U%E",base) |
PrintF("Value of base variable: %U%E",base) |
||
PrintF("Value of copy variable: %U%E",copy) |
PrintF("Value of copy variable: %U%E",copy) |
||
RETURN</ |
RETURN</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Create_an_object_at_a_given_address.png Screenshot from Atari 8-bit computer] |
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Create_an_object_at_a_given_address.png Screenshot from Atari 8-bit computer] |
||
Line 137: | Line 137: | ||
=={{header|Ada}}== |
=={{header|Ada}}== |
||
In [[Ada]] object address can be specified using the address representation clause [http://www.adaic.org/standards/05rm/html/RM-13-3.html RM 13.3]: |
In [[Ada]] object address can be specified using the address representation clause [http://www.adaic.org/standards/05rm/html/RM-13-3.html RM 13.3]: |
||
< |
<syntaxhighlight lang="ada"> |
||
type IO_Port is mod 2**8; -- One byte |
type IO_Port is mod 2**8; -- One byte |
||
Device_Port : type IO_Port; |
Device_Port : type IO_Port; |
||
for Device_Port'Address use 16#FFFF_F000#; |
for Device_Port'Address use 16#FFFF_F000#; |
||
</syntaxhighlight> |
|||
</lang> |
|||
In the example above the address is specified constant. It is also possible to specify address dynamically as the following solution of the task does: |
In the example above the address is specified constant. It is also possible to specify address dynamically as the following solution of the task does: |
||
< |
<syntaxhighlight lang="ada"> |
||
with Ada.Text_IO; use Ada.Text_IO; |
with Ada.Text_IO; use Ada.Text_IO; |
||
with System.Storage_Elements; use System.Storage_Elements; |
with System.Storage_Elements; use System.Storage_Elements; |
||
Line 157: | Line 157: | ||
Put_Line (Integer'Image (Y)); |
Put_Line (Integer'Image (Y)); |
||
end Test_Address; |
end Test_Address; |
||
</syntaxhighlight> |
|||
</lang> |
|||
Sample output: |
Sample output: |
||
<pre> |
<pre> |
||
Line 167: | Line 167: | ||
=={{header|Aikido}}== |
=={{header|Aikido}}== |
||
Aikido doesn't support getting the address of a variable. However, in the spirit of this task, it does support raw memory access using <code>peek</code> and <code>poke</code>. These can be used on both an integer representing an address (64 bit) or a value obtained from calling <code>malloc</code>. |
Aikido doesn't support getting the address of a variable. However, in the spirit of this task, it does support raw memory access using <code>peek</code> and <code>poke</code>. These can be used on both an integer representing an address (64 bit) or a value obtained from calling <code>malloc</code>. |
||
< |
<syntaxhighlight lang="aikido"> |
||
var portaddr = 0x80 |
var portaddr = 0x80 |
||
Line 179: | Line 179: | ||
poke (addr+6, 12, 2) |
poke (addr+6, 12, 2) |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Applesoft BASIC}}== |
=={{header|Applesoft BASIC}}== |
||
< |
<syntaxhighlight lang="gwbasic"> 0 DEF FN P(A) = PEEK (A) + PEEK (A + 1) * 256 |
||
100 : |
100 : |
||
110 REM CREATE AN INTEGER OBJECT |
110 REM CREATE AN INTEGER OBJECT |
||
Line 210: | Line 210: | ||
530 POKE FN P( FN P(236) + 1),69 |
530 POKE FN P( FN P(236) + 1),69 |
||
540 PRINT "NEW INTEGER VALUE : " ASC (I$) |
540 PRINT "NEW INTEGER VALUE : " ASC (I$) |
||
550 PRINT "COMPARE OTHER INTEGER : " ASC (O$)</ |
550 PRINT "COMPARE OTHER INTEGER : " ASC (O$)</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 223: | Line 223: | ||
First, an integer object will be created at address $100000: |
First, an integer object will be created at address $100000: |
||
< |
<syntaxhighlight lang="arm assembly">mov r0,#0x00100000 |
||
ldr r1,testData |
ldr r1,testData |
||
str r1,[r0] ;store 0x12345678 at address $100000 |
str r1,[r0] ;store 0x12345678 at address $100000 |
||
Line 229: | Line 229: | ||
testData: |
testData: |
||
.long 0x12345678 ;VASM uses .long for 32 bit and .word for 16 bit values, unlike most ARM assemblers.</ |
.long 0x12345678 ;VASM uses .long for 32 bit and .word for 16 bit values, unlike most ARM assemblers.</syntaxhighlight> |
||
Finding the address of a given object isn't actually possible in the same way it would be on [[C]], since anything loaded from an address is just a numeric copy and is not actually related in any way to the "object." The closest way is to label a memory address and load that label as a numeric constant. |
Finding the address of a given object isn't actually possible in the same way it would be on [[C]], since anything loaded from an address is just a numeric copy and is not actually related in any way to the "object." The closest way is to label a memory address and load that label as a numeric constant. |
||
< |
<syntaxhighlight lang="arm assembly">.equ myVariable,0x00100000 |
||
mov r0,#myVariable |
mov r0,#myVariable |
||
bl printLong ;unimplemented printing routine</ |
bl printLong ;unimplemented printing routine</syntaxhighlight> |
||
Creating a new object at that location is as simple as storing a new value there. |
Creating a new object at that location is as simple as storing a new value there. |
||
< |
<syntaxhighlight lang="arm assembly">mov r0,#0x00100000 |
||
mov r1,#0 |
mov r1,#0 |
||
mvn r1,r1 ;flip the bits of r1 |
mvn r1,r1 ;flip the bits of r1 |
||
str r1,[r0] ;store 0xFFFFFFFF at address $100000 |
str r1,[r0] ;store 0xFFFFFFFF at address $100000 |
||
bx lr ;return from subroutine</ |
bx lr ;return from subroutine</syntaxhighlight> |
||
=={{header|AutoHotkey}}== |
=={{header|AutoHotkey}}== |
||
In AutoHotkey indeed no language objects can be created at a specified address. But it's very well possible to read and write memory addresses directly. All standard number types are allowed. |
In AutoHotkey indeed no language objects can be created at a specified address. But it's very well possible to read and write memory addresses directly. All standard number types are allowed. |
||
< |
<syntaxhighlight lang="autohotkey">; Create a variable with 4 bytes size and show it's machine address. |
||
VarSetCapacity(var, 4, 0) |
VarSetCapacity(var, 4, 0) |
||
pAddress := &var |
pAddress := &var |
||
Line 254: | Line 254: | ||
; Write a number and read it back. |
; Write a number and read it back. |
||
NumPut(123456, pAddress+0, 0, "UInt") |
NumPut(123456, pAddress+0, 0, "UInt") |
||
MsgBox % "Contents of *pAddress: " . NumGet(pAddress+0, 0, "UInt")</ |
MsgBox % "Contents of *pAddress: " . NumGet(pAddress+0, 0, "UInt")</syntaxhighlight> |
||
=={{header|BBC BASIC}}== |
=={{header|BBC BASIC}}== |
||
< |
<syntaxhighlight lang="bbcbasic"> REM Create an integer object: |
||
anInteger% = 12345678 |
anInteger% = 12345678 |
||
PRINT "Original value =", anInteger% |
PRINT "Original value =", anInteger% |
||
Line 276: | Line 276: | ||
anInteger% = 55555555 |
anInteger% = 55555555 |
||
PRINT "Final value =", !address% |
PRINT "Final value =", !address% |
||
</syntaxhighlight> |
|||
</lang> |
|||
Output: |
Output: |
||
<pre>Original value = 12345678 |
<pre>Original value = 12345678 |
||
Line 284: | Line 284: | ||
=={{header|C}}== |
=={{header|C}}== |
||
< |
<syntaxhighlight lang="c">#include <stdio.h> |
||
int main() |
int main() |
||
Line 302: | Line 302: | ||
printf("%p: %08x (=%08x)\n", address, *address, intspace); |
printf("%p: %08x (=%08x)\n", address, *address, intspace); |
||
return 0; |
return 0; |
||
}</ |
}</syntaxhighlight> |
||
<pre>0xbfc5675c: 0000ffff (=0000ffff) |
<pre>0xbfc5675c: 0000ffff (=0000ffff) |
||
Line 308: | Line 308: | ||
A more typical embedded way of doing this is below. Note that the OS will probably not allow this due to memory protections. Embedded systems often do not have memory managers. |
A more typical embedded way of doing this is below. Note that the OS will probably not allow this due to memory protections. Embedded systems often do not have memory managers. |
||
< |
<syntaxhighlight lang="c">#include <stdint.h> |
||
#include <stddef.h> |
#include <stddef.h> |
||
Line 324: | Line 324: | ||
return 0; |
return 0; |
||
}</ |
}</syntaxhighlight> |
||
=={{header|C++}}== |
=={{header|C++}}== |
||
C++ supports this natively through placement new. This allows construction of complex object types in arbitrary memory locations. |
C++ supports this natively through placement new. This allows construction of complex object types in arbitrary memory locations. |
||
< |
<syntaxhighlight lang="cpp">#include <string> |
||
#include <iostream> |
#include <iostream> |
||
Line 351: | Line 351: | ||
stringPtr->~basic_string(); |
stringPtr->~basic_string(); |
||
delete[] data; |
delete[] data; |
||
}</ |
}</syntaxhighlight> |
||
Sample output: |
Sample output: |
||
Line 363: | Line 363: | ||
{{works with|COBOL|2002}} |
{{works with|COBOL|2002}} |
||
{{works with|OpenCOBOL|1.1}} |
{{works with|OpenCOBOL|1.1}} |
||
< |
<syntaxhighlight lang="cobol"> IDENTIFICATION DIVISION. |
||
PROGRAM-ID. object-address-test. |
PROGRAM-ID. object-address-test. |
||
DATA DIVISION. |
DATA DIVISION. |
||
Line 383: | Line 383: | ||
STOP RUN. |
STOP RUN. |
||
END PROGRAM object-address-test. |
END PROGRAM object-address-test. |
||
</syntaxhighlight> |
|||
</lang> |
|||
Output: |
Output: |
||
Line 395: | Line 395: | ||
=={{header|Commodore BASIC}}== |
=={{header|Commodore BASIC}}== |
||
The <code>PEEK</code> and <code>POKE</code> commands allow the [[Commodore BASIC]] user to perform limited [[6502 Assembly]] operations. |
The <code>PEEK</code> and <code>POKE</code> commands allow the [[Commodore BASIC]] user to perform limited [[6502 Assembly]] operations. |
||
< |
<syntaxhighlight lang="gwbasic">10 POKE 50000,(3) REM EQUIVALENT OF LDA #$03 STA 50000 |
||
20 PEEK(50000) REM READ THE VALUE AT MEMORY ADDRESS 50000</ |
20 PEEK(50000) REM READ THE VALUE AT MEMORY ADDRESS 50000</syntaxhighlight> |
||
=={{header|D}}== |
=={{header|D}}== |
||
A better presentation. |
A better presentation. |
||
< |
<syntaxhighlight lang="d">import std.stdio ; |
||
void main() { |
void main() { |
||
Line 434: | Line 434: | ||
*fPtr = 0.5f ; // change value |
*fPtr = 0.5f ; // change value |
||
writefln("arr[3] = 0x%8x (%9.4f) @ 0x%08X", *iPtr, *fPtr, iPtr) ; |
writefln("arr[3] = 0x%8x (%9.4f) @ 0x%08X", *iPtr, *fPtr, iPtr) ; |
||
}</ |
}</syntaxhighlight> |
||
output: |
output: |
||
<pre>arr(as X)'s msg = '~~~A~~~B~~~C~~~D' (len 16) @ 0x401C2F80 |
<pre>arr(as X)'s msg = '~~~A~~~B~~~C~~~D' (len 16) @ 0x401C2F80 |
||
Line 442: | Line 442: | ||
</pre> |
</pre> |
||
=={{header|Delphi}}== |
=={{header|Delphi}}== |
||
<syntaxhighlight lang="delphi"> |
|||
<lang Delphi> |
|||
program Create_an_object_at_a_given_address; |
program Create_an_object_at_a_given_address; |
||
Line 470: | Line 470: | ||
Readln; |
Readln; |
||
end.</ |
end.</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>The "origem" adress is: 4261256 |
<pre>The "origem" adress is: 4261256 |
||
Line 485: | Line 485: | ||
=={{header|Forth}}== |
=={{header|Forth}}== |
||
As an untyped language, specific machine addresses are very easy to represent in Forth. This is usually most useful for embedded targets. |
As an untyped language, specific machine addresses are very easy to represent in Forth. This is usually most useful for embedded targets. |
||
< |
<syntaxhighlight lang="forth"> |
||
$3f8 constant LPT1: |
$3f8 constant LPT1: |
||
LPT1: c@ . |
LPT1: c@ . |
||
$3f LPT1: c! |
$3f LPT1: c! |
||
</syntaxhighlight> |
|||
</lang> |
|||
Some architectures may require special fetch and store operators to access ports. For example, [[Open Firmware]] defines l@ and l! for safe 32-bit port writes. |
Some architectures may require special fetch and store operators to access ports. For example, [[Open Firmware]] defines l@ and l! for safe 32-bit port writes. |
||
=={{header|FreeBASIC}}== |
=={{header|FreeBASIC}}== |
||
< |
<syntaxhighlight lang="freebasic">' FB 1.05.0 |
||
Type Person |
Type Person |
||
Line 527: | Line 527: | ||
Print |
Print |
||
Print "Press any key to quit" |
Print "Press any key to quit" |
||
Sleep</ |
Sleep</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 537: | Line 537: | ||
=={{header|Go}}== |
=={{header|Go}}== |
||
Go has several ways to access arbitrary memory locations using the built-in unsafe package. If the desired memory contains an array, since Go doesn't have pointer arithmetic, then a slice should be used instead of a pointer. The following solution demonstrates both a pointer and a slice. |
Go has several ways to access arbitrary memory locations using the built-in unsafe package. If the desired memory contains an array, since Go doesn't have pointer arithmetic, then a slice should be used instead of a pointer. The following solution demonstrates both a pointer and a slice. |
||
< |
<syntaxhighlight lang="go">package main |
||
import( |
import( |
||
Line 594: | Line 594: | ||
slice() |
slice() |
||
}</ |
}</syntaxhighlight> |
||
Output: |
Output: |
||
<pre> |
<pre> |
||
Line 620: | Line 620: | ||
address of a Julia integer variable within the VM may change when it is |
address of a Julia integer variable within the VM may change when it is |
||
re-assigned a new value, an array of a single integer is used below. |
re-assigned a new value, an array of a single integer is used below. |
||
< |
<syntaxhighlight lang="julia"> |
||
function unsafepointers() |
function unsafepointers() |
||
intspace = [42] |
intspace = [42] |
||
Line 634: | Line 634: | ||
unsafepointers() |
unsafepointers() |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{output}}<pre> |
{{output}}<pre> |
||
The address of intspace is Ptr{Void} @0x0000000007271030 |
The address of intspace is Ptr{Void} @0x0000000007271030 |
||
Line 644: | Line 644: | ||
=={{header|Kotlin}}== |
=={{header|Kotlin}}== |
||
{{Works with|Ubuntu|14.04}} |
{{Works with|Ubuntu|14.04}} |
||
< |
<syntaxhighlight lang="scala">// Kotlin/Native Technology Preview |
||
import kotlinx.cinterop.* |
import kotlinx.cinterop.* |
||
Line 654: | Line 654: | ||
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 665: | Line 665: | ||
=={{header|Lua}}== |
=={{header|Lua}}== |
||
Lua has addresses by tables: |
Lua has addresses by tables: |
||
< |
<syntaxhighlight lang="lua">local a = {10} |
||
local b = a |
local b = a |
||
Line 674: | Line 674: | ||
print ("address a:"..tostring(a), "value a:"..a[1]) |
print ("address a:"..tostring(a), "value a:"..a[1]) |
||
print ("address b:"..tostring(b), "value b:"..b[1])</ |
print ("address b:"..tostring(b), "value b:"..b[1])</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 690: | Line 690: | ||
Memory addresses are nit the physical address, it's from virtual space. |
Memory addresses are nit the physical address, it's from virtual space. |
||
<syntaxhighlight lang="m2000 interpreter"> |
|||
<lang M2000 Interpreter> |
|||
Module CheckIt { |
Module CheckIt { |
||
structure alfa { |
structure alfa { |
||
Line 728: | Line 728: | ||
} |
} |
||
Checkit |
Checkit |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Nim}}== |
=={{header|Nim}}== |
||
< |
<syntaxhighlight lang="nim">type |
||
MyObject = object |
MyObject = object |
||
x: int |
x: int |
||
Line 744: | Line 744: | ||
objPtr[] = MyObject(x: 42, y: 3.1415) |
objPtr[] = MyObject(x: 42, y: 3.1415) |
||
echo "object at ", cast[int](mem), ": ", objPtr[] |
echo "object at ", cast[int](mem), ": ", objPtr[] |
||
</syntaxhighlight> |
|||
</lang> |
|||
Output: |
Output: |
||
Line 754: | Line 754: | ||
This works for global variables too: |
This works for global variables too: |
||
< |
<syntaxhighlight lang="nim">var x: int = 3 |
||
var p: ptr int |
var p: ptr int |
||
Line 761: | Line 761: | ||
echo "Before ", x |
echo "Before ", x |
||
p[] = 5 |
p[] = 5 |
||
echo "After: ", x</ |
echo "After: ", x</syntaxhighlight> |
||
Output: |
Output: |
||
Line 770: | Line 770: | ||
Like in Ada you can assigne different variables at the same adress of an already declared variable. |
Like in Ada you can assigne different variables at the same adress of an already declared variable. |
||
Nice to get the bytes out of an Int64. |
Nice to get the bytes out of an Int64. |
||
< |
<syntaxhighlight lang="pascal">program test; |
||
type |
type |
||
t8Byte = array[0..7] of byte; |
t8Byte = array[0..7] of byte; |
||
Line 790: | Line 790: | ||
writeln(#8#32); |
writeln(#8#32); |
||
writeln(L); |
writeln(L); |
||
end.</ |
end.</syntaxhighlight>{OUT}<pre>255 |
||
4711 |
4711 |
||
0 1 2 3 4 5 6 7 |
0 1 2 3 4 5 6 7 |
||
Line 797: | Line 797: | ||
=={{header|Perl}}== |
=={{header|Perl}}== |
||
The is basically a simplified version of the solution to the [https://rosettacode.org/wiki/Address_of_a_variable#Perl Address of a variable] task, so for more detail please consult that entry. |
The is basically a simplified version of the solution to the [https://rosettacode.org/wiki/Address_of_a_variable#Perl Address of a variable] task, so for more detail please consult that entry. |
||
< |
<syntaxhighlight lang="perl"># 20210218 Perl programming solution |
||
use strict; |
use strict; |
||
Line 816: | Line 816: | ||
# print the value of this object to verify that it is same as one of the origin |
# print the value of this object to verify that it is same as one of the origin |
||
print "Then compare with the referent : ", $target, "\n"; </ |
print "Then compare with the referent : ", $target, "\n"; </syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 828: | Line 828: | ||
Phix does not support creation of a "language object" at a specific address, but you can peek and poke bytes, words, dwords and qwords |
Phix does not support creation of a "language object" at a specific address, but you can peek and poke bytes, words, dwords and qwords |
||
to any address, as long as doing so does not trigger a hardware exception. You could also use inline assembly, if that helps any. |
to any address, as long as doing so does not trigger a hardware exception. You could also use inline assembly, if that helps any. |
||
<!--< |
<!--<syntaxhighlight lang="phix">--> |
||
<span style="color: #7060A8;">poke</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0x80</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">or_bits</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">peek</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0x80</span><span style="color: #0000FF;">),</span><span style="color: #000000;">0x40</span><span style="color: #0000FF;">))</span> |
<span style="color: #7060A8;">poke</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0x80</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">or_bits</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">peek</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0x80</span><span style="color: #0000FF;">),</span><span style="color: #000000;">0x40</span><span style="color: #0000FF;">))</span> |
||
#ilASM{ mov al,[0x80] |
#ilASM{ mov al,[0x80] |
||
or al,0x40 |
or al,0x40 |
||
mov [0x80],al} |
mov [0x80],al} |
||
<!--</ |
<!--</syntaxhighlight>--> |
||
=={{header|PicoLisp}}== |
=={{header|PicoLisp}}== |
||
< |
<syntaxhighlight lang="picolisp">: (setq IntSpace 12345) # Integer |
||
-> 12345 |
-> 12345 |
||
Line 846: | Line 846: | ||
: IntSpace # Show the new value |
: IntSpace # Show the new value |
||
-> 65535</ |
-> 65535</syntaxhighlight> |
||
=={{header|PureBasic}}== |
=={{header|PureBasic}}== |
||
< |
<syntaxhighlight lang="purebasic">; Allocate a 1Mb memory area work within to avoid conflicts, |
||
; this address could be any number but it may then fail on some systems. |
; this address could be any number but it may then fail on some systems. |
||
*a=AllocateMemory(1024*1024) |
*a=AllocateMemory(1024*1024) |
||
Line 870: | Line 870: | ||
EndIf |
EndIf |
||
Next |
Next |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Racket}}== |
=={{header|Racket}}== |
||
< |
<syntaxhighlight lang="racket"> |
||
#lang racket |
#lang racket |
||
(require ffi/unsafe) |
(require ffi/unsafe) |
||
Line 899: | Line 899: | ||
;; or start with a given address of something like a memory-mapped IO |
;; or start with a given address of something like a memory-mapped IO |
||
;; object |
;; object |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Raku}}== |
=={{header|Raku}}== |
||
(formerly Perl 6) |
(formerly Perl 6) |
||
Raku has fairly comprehensive facilities for accessing allocating and accessing memory and also declaring C-style structs, via the NativeCall interface, as this example demonstrates. |
Raku has fairly comprehensive facilities for accessing allocating and accessing memory and also declaring C-style structs, via the NativeCall interface, as this example demonstrates. |
||
<lang |
<syntaxhighlight lang="raku" line>use NativeCall; |
||
use NativeCall::Types; |
use NativeCall::Types; |
||
Line 960: | Line 960: | ||
free($base-p); |
free($base-p); |
||
done-testing; |
done-testing; |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre>creating object at address 94299589110352 |
<pre>creating object at address 94299589110352 |
||
Line 972: | Line 972: | ||
=={{header|Rust}}== |
=={{header|Rust}}== |
||
In a real program, most if not all of the contents of main would all be in one `unsafe` block, however in this one each unsafe operation gets its own block to emphasize exactly which actions Rust considers unsafe. |
In a real program, most if not all of the contents of main would all be in one `unsafe` block, however in this one each unsafe operation gets its own block to emphasize exactly which actions Rust considers unsafe. |
||
< |
<syntaxhighlight lang="rust">use std::{mem,ptr}; |
||
fn main() { |
fn main() { |
||
Line 990: | Line 990: | ||
println!("{0:p}: {0}", &data); |
println!("{0:p}: {0}", &data); |
||
}</ |
}</syntaxhighlight> |
||
=={{header|S-BASIC}}== |
=={{header|S-BASIC}}== |
||
S-BASIC fully supports "based" variables that can be positioned at run-time. |
S-BASIC fully supports "based" variables that can be positioned at run-time. |
||
<syntaxhighlight lang="basic"> |
|||
<lang BASIC> |
|||
var first, addr = integer |
var first, addr = integer |
||
based second = integer |
based second = integer |
||
Line 1,008: | Line 1,008: | ||
end |
end |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 1,027: | Line 1,027: | ||
{{libheader|critcl}} |
{{libheader|critcl}} |
||
< |
<syntaxhighlight lang="tcl">package require critcl |
||
# A command to 'make an integer object' and couple it to a Tcl variable |
# A command to 'make an integer object' and couple it to a Tcl variable |
||
Line 1,047: | Line 1,047: | ||
# Conventionally, programs that use critcl structure in packages |
# Conventionally, programs that use critcl structure in packages |
||
# This is used to prevent recompilation, especially on systems like Windows |
# This is used to prevent recompilation, especially on systems like Windows |
||
package provide machAddrDemo 1</ |
package provide machAddrDemo 1</syntaxhighlight> |
||
Demonstrating: |
Demonstrating: |
||
< |
<syntaxhighlight lang="tcl">package require machAddrDemo |
||
set addr [linkvar foo] |
set addr [linkvar foo] |
||
puts "var 'foo' at $addr with value $foo" |
puts "var 'foo' at $addr with value $foo" |
||
Line 1,055: | Line 1,055: | ||
puts "var 'bar' at $addr with value $bar" |
puts "var 'bar' at $addr with value $bar" |
||
incr foo |
incr foo |
||
puts "incremented 'foo' so 'bar' is $bar"</ |
puts "incremented 'foo' so 'bar' is $bar"</syntaxhighlight> |
||
Example output (your mileage may vary when it comes to addresses): |
Example output (your mileage may vary when it comes to addresses): |
||
<pre>var 'foo' at 19363848 with value 0 |
<pre>var 'foo' at 19363848 with value 0 |
||
Line 1,071: | Line 1,071: | ||
Note that it is not possible to specify the address at which the embedding API function ''wrenSetSlotNewForeign'' allocates new objects and any attempt to allocate a new object at the same address as an old one by juggling with pointers will almost certainly lead to a seg fault. So all we can sensibly do is to change the value of the current object. |
Note that it is not possible to specify the address at which the embedding API function ''wrenSetSlotNewForeign'' allocates new objects and any attempt to allocate a new object at the same address as an old one by juggling with pointers will almost certainly lead to a seg fault. So all we can sensibly do is to change the value of the current object. |
||
< |
<syntaxhighlight lang="ecmascript">/* create_object_at_given_address.wren */ |
||
import "./fmt" for Fmt |
import "./fmt" for Fmt |
||
Line 1,090: | Line 1,090: | ||
Fmt.print("Integer object value reset to: $d but still at address $#x.", i.value, i.address) |
Fmt.print("Integer object value reset to: $d but still at address $#x.", i.value, i.address) |
||
i.value = 43 |
i.value = 43 |
||
Fmt.print("Integer object value changed to: $d but still at address $#x.", i.value, i.address)</ |
Fmt.print("Integer object value changed to: $d but still at address $#x.", i.value, i.address)</syntaxhighlight> |
||
<br> |
<br> |
||
We now embed this in the following C program, compile and run it. |
We now embed this in the following C program, compile and run it. |
||
< |
<syntaxhighlight lang="c">/* gcc create_object_at_given_address.c -o create_object_at_given_address -lwren -lm */ |
||
#include <stdio.h> |
#include <stdio.h> |
||
Line 1,224: | Line 1,224: | ||
free(script); |
free(script); |
||
return 0; |
return 0; |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,236: | Line 1,236: | ||
When writing assembly yourself, you'll know any object's memory location in advance. |
When writing assembly yourself, you'll know any object's memory location in advance. |
||
This code creates the 16-bit integer object 0xFFFF at memory address 0xC000: |
This code creates the 16-bit integer object 0xFFFF at memory address 0xC000: |
||
< |
<syntaxhighlight lang="z80">LD HL,&FFFF |
||
LD (&C000),HL</ |
LD (&C000),HL</syntaxhighlight> |
||
Loading a value into a register from memory only loads a copy; the original value at that memory location isn't altered, nor is the memory location of that value. Assume this code is executed immediately after the above example: |
Loading a value into a register from memory only loads a copy; the original value at that memory location isn't altered, nor is the memory location of that value. Assume this code is executed immediately after the above example: |
||
< |
<syntaxhighlight lang="z80">LD HL,(&C000) ;load &FFFF into HL |
||
INC HL ;HL now equals &0000 |
INC HL ;HL now equals &0000 |
||
LD BC,(&C000) ;load &FFFF into BC.</ |
LD BC,(&C000) ;load &FFFF into BC.</syntaxhighlight> |
||
In order to change a value at a memory location, it either needs to be loaded into a register and stored back after altering that register in some way, or by using certain indirect addressing modes, like so: |
In order to change a value at a memory location, it either needs to be loaded into a register and stored back after altering that register in some way, or by using certain indirect addressing modes, like so: |
||
< |
<syntaxhighlight lang="z80">LD HL,&C000 ;get the address of our variable. |
||
INC (hl) ;increment the low byte. |
INC (hl) ;increment the low byte. |
||
LD HL,(&C000) ;load &FF00 into HL.</ |
LD HL,(&C000) ;load &FF00 into HL.</syntaxhighlight> |
||
If you're not familiar with the Z80's syntax, this can be a bit confusing. The brackets are like the dereference operator in C, and not having brackets is like the unary <code>&</code> operator in C. The Z80's ability to do 16-bit operations is limited; it can load from two consecutive memory locations into a 16-bit register pair, however when using <code>(hl)</code> as an operand it is only operating on the lower 8 bits. When learning Z80 Assembly, it is very helpful to view a hex editor while learning the instruction set. |
If you're not familiar with the Z80's syntax, this can be a bit confusing. The brackets are like the dereference operator in C, and not having brackets is like the unary <code>&</code> operator in C. The Z80's ability to do 16-bit operations is limited; it can load from two consecutive memory locations into a 16-bit register pair, however when using <code>(hl)</code> as an operand it is only operating on the lower 8 bits. When learning Z80 Assembly, it is very helpful to view a hex editor while learning the instruction set. |