Create an object at a given address: Difference between revisions

m
syntax highlighting fixup automation
m (syntax highlighting fixup automation)
Line 23:
 
Data can be stored, one byte at a time, through the store instructions, for example to store data at $1900:
<langsyntaxhighlight lang="6502asm"> sta $1900
stx $1901
sty $1902</langsyntaxhighlight>
 
Storage can be indexed through the use of the X or Y registers:
<langsyntaxhighlight lang="6502asm"> ldx #54
.loop sta $1900,X
dex
bne loop</langsyntaxhighlight>
 
It can also be stored via indirect indexed addressing (i.e. memory points to an address), using the Y register:
<langsyntaxhighlight lang="6502asm"> lda #0
sta $70
lda #$20
sta $71
ldy #0
sta ($70),Y</langsyntaxhighlight>
 
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:
<langsyntaxhighlight lang="6502asm"> lda #0
sta $70
lda #$20
sta $71
ldx #0
sta ($70,X)</langsyntaxhighlight>
 
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}}==
First, an integer object will be created at address $100000:
<syntaxhighlight lang ="68000devpac">MOVE.L #$12345678,$100000</langsyntaxhighlight>
 
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.
<langsyntaxhighlight lang="68000devpac">myVariable equ $100000
MOVE.L #myVariable,D0
JSR printLong ;some unimplemented printing routine.</langsyntaxhighlight>
 
Creating a new object at that location is as simple as storing a new value there.
<syntaxhighlight lang ="68000devpac">MOVE.L #$FFFFFFFF,myVariable</langsyntaxhighlight>
 
=={{header|8086 Assembly}}==
This example uses UASM to assemble MS-DOS compatible code.
<langsyntaxhighlight lang="asm">.model small ;specify memory model to use
.stack 1024 ;set up stack
 
Line 95:
 
;get the address of a variable
mov ax, tempLong_LoWord ;without "word ptr" and brackets, the assembler interprets a label as a constant.</langsyntaxhighlight>
 
=={{header|Action!}}==
<langsyntaxhighlight Actionlang="action!">DEFINE FIRST="12345"
DEFINE SECOND="54321"
DEFINE PTR="CARD"
Line 119:
PrintF("Value of base variable: %U%E",base)
PrintF("Value of copy variable: %U%E",copy)
RETURN</langsyntaxhighlight>
{{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]
Line 137:
=={{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]:
<langsyntaxhighlight lang="ada">
type IO_Port is mod 2**8; -- One byte
Device_Port : type IO_Port;
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:
<langsyntaxhighlight lang="ada">
with Ada.Text_IO; use Ada.Text_IO;
with System.Storage_Elements; use System.Storage_Elements;
Line 157:
Put_Line (Integer'Image (Y));
end Test_Address;
</syntaxhighlight>
</lang>
Sample output:
<pre>
Line 167:
=={{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>.
<langsyntaxhighlight lang="aikido">
 
var portaddr = 0x80
Line 179:
poke (addr+6, 12, 2)
 
</syntaxhighlight>
</lang>
=={{header|Applesoft BASIC}}==
<langsyntaxhighlight lang="gwbasic"> 0 DEF FN P(A) = PEEK (A) + PEEK (A + 1) * 256
100 :
110 REM CREATE AN INTEGER OBJECT
Line 210:
530 POKE FN P( FN P(236) + 1),69
540 PRINT "NEW INTEGER VALUE : " ASC (I$)
550 PRINT "COMPARE OTHER INTEGER : " ASC (O$)</langsyntaxhighlight>
{{out}}
<pre>
Line 223:
 
First, an integer object will be created at address $100000:
<langsyntaxhighlight ARMlang="arm Assemblyassembly">mov r0,#0x00100000
ldr r1,testData
str r1,[r0] ;store 0x12345678 at address $100000
Line 229:
 
testData:
.long 0x12345678 ;VASM uses .long for 32 bit and .word for 16 bit values, unlike most ARM assemblers.</langsyntaxhighlight>
 
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.
<langsyntaxhighlight ARMlang="arm Assemblyassembly">.equ myVariable,0x00100000
mov r0,#myVariable
bl printLong ;unimplemented printing routine</langsyntaxhighlight>
 
Creating a new object at that location is as simple as storing a new value there.
<langsyntaxhighlight ARMlang="arm Assemblyassembly">mov r0,#0x00100000
mov r1,#0
mvn r1,r1 ;flip the bits of r1
str r1,[r0] ;store 0xFFFFFFFF at address $100000
bx lr ;return from subroutine</langsyntaxhighlight>
 
=={{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.
 
<langsyntaxhighlight AutoHotkeylang="autohotkey">; Create a variable with 4 bytes size and show it's machine address.
VarSetCapacity(var, 4, 0)
pAddress := &var
Line 254:
; Write a number and read it back.
NumPut(123456, pAddress+0, 0, "UInt")
MsgBox % "Contents of *pAddress: " . NumGet(pAddress+0, 0, "UInt")</langsyntaxhighlight>
 
=={{header|BBC BASIC}}==
<langsyntaxhighlight lang="bbcbasic"> REM Create an integer object:
anInteger% = 12345678
PRINT "Original value =", anInteger%
Line 276:
anInteger% = 55555555
PRINT "Final value =", !address%
</syntaxhighlight>
</lang>
Output:
<pre>Original value = 12345678
Line 284:
 
=={{header|C}}==
<langsyntaxhighlight lang="c">#include <stdio.h>
 
int main()
Line 302:
printf("%p: %08x (=%08x)\n", address, *address, intspace);
return 0;
}</langsyntaxhighlight>
 
<pre>0xbfc5675c: 0000ffff (=0000ffff)
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.
<langsyntaxhighlight lang="c">#include <stdint.h>
#include <stddef.h>
 
Line 324:
 
return 0;
}</langsyntaxhighlight>
 
=={{header|C++}}==
C++ supports this natively through placement new. This allows construction of complex object types in arbitrary memory locations.
<langsyntaxhighlight Cpplang="cpp">#include <string>
#include <iostream>
 
Line 351:
stringPtr->~basic_string();
delete[] data;
}</langsyntaxhighlight>
 
Sample output:
Line 363:
{{works with|COBOL|2002}}
{{works with|OpenCOBOL|1.1}}
<langsyntaxhighlight COBOLlang="cobol"> IDENTIFICATION DIVISION.
PROGRAM-ID. object-address-test.
DATA DIVISION.
Line 383:
STOP RUN.
END PROGRAM object-address-test.
</syntaxhighlight>
</lang>
 
Output:
Line 395:
=={{header|Commodore BASIC}}==
The <code>PEEK</code> and <code>POKE</code> commands allow the [[Commodore BASIC]] user to perform limited [[6502 Assembly]] operations.
<langsyntaxhighlight lang="gwbasic">10 POKE 50000,(3) REM EQUIVALENT OF LDA #$03 STA 50000
20 PEEK(50000) REM READ THE VALUE AT MEMORY ADDRESS 50000</langsyntaxhighlight>
 
=={{header|D}}==
 
A better presentation.
<langsyntaxhighlight lang="d">import std.stdio ;
 
void main() {
Line 434:
*fPtr = 0.5f ; // change value
writefln("arr[3] = 0x%8x (%9.4f) @ 0x%08X", *iPtr, *fPtr, iPtr) ;
}</langsyntaxhighlight>
output:
<pre>arr(as X)'s msg = '~~~A~~~B~~~C~~~D' (len 16) @ 0x401C2F80
Line 442:
</pre>
=={{header|Delphi}}==
<syntaxhighlight lang="delphi">
<lang Delphi>
program Create_an_object_at_a_given_address;
 
Line 470:
Readln;
 
end.</langsyntaxhighlight>
{{out}}
<pre>The "origem" adress is: 4261256
Line 485:
=={{header|Forth}}==
As an untyped language, specific machine addresses are very easy to represent in Forth. This is usually most useful for embedded targets.
<langsyntaxhighlight lang="forth">
$3f8 constant LPT1:
 
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.
 
=={{header|FreeBASIC}}==
<langsyntaxhighlight lang="freebasic">' FB 1.05.0
 
Type Person
Line 527:
Print
Print "Press any key to quit"
Sleep</langsyntaxhighlight>
 
{{out}}
Line 537:
=={{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.
<langsyntaxhighlight lang="go">package main
 
import(
Line 594:
 
slice()
}</langsyntaxhighlight>
Output:
<pre>
Line 620:
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.
<langsyntaxhighlight lang="julia">
function unsafepointers()
intspace = [42]
Line 634:
 
unsafepointers()
</syntaxhighlight>
</lang>
{{output}}<pre>
The address of intspace is Ptr{Void} @0x0000000007271030
Line 644:
=={{header|Kotlin}}==
{{Works with|Ubuntu|14.04}}
<langsyntaxhighlight lang="scala">// Kotlin/Native Technology Preview
 
import kotlinx.cinterop.*
Line 654:
with(intVar) { println("Value is $value, address is $rawPtr") }
nativeHeap.free(intVar)
}</langsyntaxhighlight>
 
{{out}}
Line 665:
=={{header|Lua}}==
Lua has addresses by tables:
<langsyntaxhighlight Lualang="lua">local a = {10}
local b = a
 
Line 674:
 
print ("address a:"..tostring(a), "value a:"..a[1])
print ("address b:"..tostring(b), "value b:"..b[1])</langsyntaxhighlight>
 
{{out}}
Line 690:
 
Memory addresses are nit the physical address, it's from virtual space.
<syntaxhighlight lang="m2000 interpreter">
<lang M2000 Interpreter>
Module CheckIt {
structure alfa {
Line 728:
}
Checkit
</syntaxhighlight>
</lang>
 
=={{header|Nim}}==
 
<langsyntaxhighlight lang="nim">type
MyObject = object
x: int
Line 744:
objPtr[] = MyObject(x: 42, y: 3.1415)
echo "object at ", cast[int](mem), ": ", objPtr[]
</syntaxhighlight>
</lang>
 
Output:
Line 754:
This works for global variables too:
 
<langsyntaxhighlight Nimlang="nim">var x: int = 3
var p: ptr int
 
Line 761:
echo "Before ", x
p[] = 5
echo "After: ", x</langsyntaxhighlight>
 
Output:
Line 770:
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.
<langsyntaxhighlight lang="pascal">program test;
type
t8Byte = array[0..7] of byte;
Line 790:
writeln(#8#32);
writeln(L);
end.</langsyntaxhighlight>{OUT}<pre>255
4711
0 1 2 3 4 5 6 7
Line 797:
=={{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.
<langsyntaxhighlight lang="perl"># 20210218 Perl programming solution
 
use strict;
Line 816:
# 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"; </langsyntaxhighlight>
{{out}}
<pre>
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
to any address, as long as doing so does not trigger a hardware exception. You could also use inline assembly, if that helps any.
<!--<langsyntaxhighlight Phixlang="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>
#ilASM{ mov al,[0x80]
or al,0x40
mov [0x80],al}
<!--</langsyntaxhighlight>-->
 
=={{header|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp">: (setq IntSpace 12345) # Integer
-> 12345
 
Line 846:
 
: IntSpace # Show the new value
-> 65535</langsyntaxhighlight>
 
=={{header|PureBasic}}==
<langsyntaxhighlight PureBasiclang="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.
*a=AllocateMemory(1024*1024)
Line 870:
EndIf
Next
</syntaxhighlight>
</lang>
 
=={{header|Racket}}==
<langsyntaxhighlight lang="racket">
#lang racket
(require ffi/unsafe)
Line 899:
;; or start with a given address of something like a memory-mapped IO
;; object
</syntaxhighlight>
</lang>
 
=={{header|Raku}}==
(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.
<syntaxhighlight lang="raku" perl6line>use NativeCall;
use NativeCall::Types;
 
Line 960:
free($base-p);
done-testing;
</syntaxhighlight>
</lang>
{{out}}
<pre>creating object at address 94299589110352
Line 972:
=={{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.
<langsyntaxhighlight lang="rust">use std::{mem,ptr};
 
fn main() {
Line 990:
println!("{0:p}: {0}", &data);
 
}</langsyntaxhighlight>
 
 
=={{header|S-BASIC}}==
S-BASIC fully supports "based" variables that can be positioned at run-time.
<syntaxhighlight lang="basic">
<lang BASIC>
var first, addr = integer
based second = integer
Line 1,008:
 
end
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 1,027:
 
{{libheader|critcl}}
<langsyntaxhighlight lang="tcl">package require critcl
 
# A command to 'make an integer object' and couple it to a Tcl variable
Line 1,047:
# Conventionally, programs that use critcl structure in packages
# This is used to prevent recompilation, especially on systems like Windows
package provide machAddrDemo 1</langsyntaxhighlight>
Demonstrating:
<langsyntaxhighlight lang="tcl">package require machAddrDemo
set addr [linkvar foo]
puts "var 'foo' at $addr with value $foo"
Line 1,055:
puts "var 'bar' at $addr with value $bar"
incr foo
puts "incremented 'foo' so 'bar' is $bar"</langsyntaxhighlight>
Example output (your mileage may vary when it comes to addresses):
<pre>var 'foo' at 19363848 with value 0
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.
 
<langsyntaxhighlight lang="ecmascript">/* create_object_at_given_address.wren */
 
import "./fmt" for Fmt
Line 1,090:
Fmt.print("Integer object value reset to: $d but still at address $#x.", i.value, i.address)
i.value = 43
Fmt.print("Integer object value changed to: $d but still at address $#x.", i.value, i.address)</langsyntaxhighlight>
<br>
We now embed this in the following C program, compile and run it.
<langsyntaxhighlight lang="c">/* gcc create_object_at_given_address.c -o create_object_at_given_address -lwren -lm */
 
#include <stdio.h>
Line 1,224:
free(script);
return 0;
}</langsyntaxhighlight>
 
{{out}}
Line 1,236:
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:
<langsyntaxhighlight lang="z80">LD HL,&FFFF
LD (&C000),HL</langsyntaxhighlight>
 
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:
<langsyntaxhighlight lang="z80">LD HL,(&C000) ;load &FFFF into HL
INC HL ;HL now equals &0000
LD BC,(&C000) ;load &FFFF into BC.</langsyntaxhighlight>
 
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:
<langsyntaxhighlight lang="z80">LD HL,&C000 ;get the address of our variable.
INC (hl) ;increment the low byte.
LD HL,(&C000) ;load &FF00 into HL.</langsyntaxhighlight>
 
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.
10,327

edits