
Basic Data Operation

This is a basic data operation. It represents a fundamental action on a basic data type.
You may see other such operations in the Basic Data Operations category, or:


Integer Operations
Arithmetic |
Comparison
Boolean Operations
Bitwise |
Logical
String Operations
Concatenation |
Interpolation |
Comparison |
Matching
Memory Operations
Pointers & references |
Addresses




In systems programing it is sometimes required to place language objects at specific memory locations, like I/O registers, hardware interrupt vectors etc.



Task

Show how language objects can be allocated at a specific machine addresses.

Since most OSes prohibit access to the physical memory if it is not mapped by the application, as an example, rather than a physical address, take the address of some existing object (using suitable address operations if necessary).



For example:

   create an integer object
   print the machine address of the object
   take the address of the object and create another integer object at this address
   print the value of this object to verify that it is same as one of the origin
   change the value of the origin and verify it again


package main
 
import(
	"fmt"
	"unsafe"
	"reflect"
)
 
func pointer() {
	fmt.Printf("Pointer:\n")
 
	// Create a *int and store the address of 'i' in it. To create a pointer to
	// an arbitrary memory location, use something like the following:
	//    p := (*int)(unsafe.Pointer(uintptr(0x100)))
	// And replace '0x100' with the desired address.
	var i int
	p := &i
 
	fmt.Printf("Before:\n\t%v: %v, %v\n", p, *p, i)
 
	*p = 3
 
	fmt.Printf("After:\n\t%v: %v, %v\n", p, *p, i)
}
 
func slice() {
	fmt.Printf("Slice:\n")
 
	var a [10]byte
 
	// reflect.SliceHeader is a runtime representation of the internal workings
	// of a slice. To make it point to a specific address, use something like
	// the following:
	//    h.Data = uintptr(0x100)
	// And replace '0x100' with the desired address.
	var h reflect.SliceHeader
	h.Data = uintptr(unsafe.Pointer(&a)) // The address of the first element of the underlying array.
	h.Len = len(a)
	h.Cap = len(a)
 
	// Create an actual slice from the SliceHeader.
	s := *(*[]byte)(unsafe.Pointer(&h))
 
	fmt.Printf("Before:\n\ts: %v\n\ta: %v\n", s, a)
 
	// Copy a string into the slice. This fills the underlying array, which in
	// this case has been manually set to 'a'.
	copy(s, "A string.")
 
	fmt.Printf("After:\n\ts: %v\n\ta: %v\n", s, a)
}
 
func main() {
	pointer()
	fmt.Println()
 
	slice()
}