Machine code: Difference between revisions

Content added Content deleted
m (Clarified the program a little bit.)
(→‎{{header|Go}}: Now uses actual x64 opcodes rather than x86/x64 'glue code' .)
Line 374: Line 374:
This task requires the use of 'cgo' which enables Go to interface with C code by importing a pseudo-package called "C".
This task requires the use of 'cgo' which enables Go to interface with C code by importing a pseudo-package called "C".


Although Go supports both 32-bit and 64-bit architectures, I'm writing this on a 64-bit Ubuntu 16.04 system. I've therefore utilized the PicoLisp entry's 'glue code' to enable the 32-bit code to run on it.
Although Go supports both 32-bit and 64-bit architectures, I'm writing this on a 64-bit Ubuntu 20.04 system. I'm therefore using x64 opcodes rather than the x86 (32-bit) opcodes listed in the task description.


There doesn't appear to be a way to cast a pointer to a native buffer to a Go function pointer so that the machine code can be run directly. I've therefore written a C function to perform this step and embedded it in the program which 'cgo' allows us to do.
There doesn't appear to be a way to cast a pointer to a native buffer to a Go function pointer so that the machine code can be run directly. I've therefore written a C function to perform this step and embedded it in the program which 'cgo' allows us to do.
Line 399: Line 399:
func main() {
func main() {
code := []byte{
code := []byte{
144, // Align
0x55, 0x48, 0x89, 0xe5, 0x89, 0x7d,
144,
0xfc, 0x89, 0x75, 0xf8, 0x8b, 0x75,
106, 12, // Prepare stack
0xfc, 0x03, 0x75, 0xf8, 0x89, 0x75,
184, 7, 0, 0, 0,
0xf4, 0x8b, 0x45, 0xf4, 0x5d, 0xc3,
72, 193, 224, 32,
80,
139, 68, 36, 4, 3, 68, 36, 8, // Rosetta task code
76, 137, 227, // Get result
137, 195,
72, 193, 227, 4,
128, 203, 2,
72, 131, 196, 16, // Clean up stack
195, // Return
}
}
le := len(code)
le := len(code)