Machine code: Difference between revisions
Content added Content deleted
(Added Go) |
|||
Line 172: | Line 172: | ||
{{out}} |
{{out}} |
||
19 |
19 |
||
=={{header|Go}}== |
|||
{{trans|C}} |
|||
<br> |
|||
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. |
|||
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. |
|||
<lang go>package main |
|||
import "fmt" |
|||
/* |
|||
#include <stdio.h> |
|||
#include <stdlib.h> |
|||
#include <sys/mman.h> |
|||
#include <string.h> |
|||
typedef unsigned char byte; |
|||
typedef byte (*mcfunc) (byte, byte); |
|||
void runMachineCode(void *buf, byte a, byte b) { |
|||
mcfunc fp = (mcfunc)buf; |
|||
printf("%d\n", fp(a, b)); |
|||
} |
|||
*/ |
|||
import "C" |
|||
func main() { |
|||
code := []byte{ |
|||
144, // Align |
|||
144, |
|||
106, 12, // Prepare stack |
|||
184, 7, 0, 0, 0, |
|||
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) |
|||
buf := C.mmap(nil, C.size_t(le), C.PROT_READ|C.PROT_WRITE|C.PROT_EXEC, |
|||
C.MAP_PRIVATE|C.MAP_ANON, -1, 0) |
|||
codePtr := C.CBytes(code) |
|||
C.memcpy(buf, codePtr, C.size_t(le)) |
|||
var a, b byte = 7, 12 |
|||
fmt.Printf("%d + %d = ", a, b) |
|||
C.runMachineCode(buf, C.byte(a), C.byte(b)) |
|||
C.munmap(buf, C.size_t(le)) |
|||
C.free(codePtr) |
|||
}</lang> |
|||
{{out}} |
|||
<pre> |
|||
7 + 12 = 19 |
|||
</pre> |
|||
=={{header|Kotlin}}== |
=={{header|Kotlin}}== |