Machine code: Difference between revisions
Content added Content deleted
m (added pure ilASM example) |
(Added Kotlin) |
||
Line 172: | Line 172: | ||
{{out}} |
{{out}} |
||
19 |
19 |
||
=={{header|Kotlin}}== |
|||
{{trans|C}} |
|||
This task presents a number of issues for Kotlin Native which at the time of writing (August 2017) is still in the earlier stages of development:- |
|||
1. The language doesn't (yet) have an unsigned Byte type, though this is easily solved by subtracting 256 from unsigned values between 128 and 255 inclusive and then using the signed Byte type. |
|||
2. As far as x86 is concerned, the language is currently only targetting 64-bit platforms including Ubuntu 14.04 on which I'm writing this. Rather than rewrite the task using x64 opcodes, I've used the PicoLisp entry's 'glue code' to enable the 32-bit machine code to run on a 64-bit system. |
|||
3. There doesn't appear to be a way to cast a pointer to a native buffer to a Kotlin function pointer so that the machine code can be run. I've therefore written a 'one line' C helper function (in mcode.def) to perform this step and compiled it to a library (mcode.klib) so that it can be called from Kotlin code. |
|||
<lang C>// mcode.def |
|||
--- |
|||
static inline unsigned char runMachineCode(void *code, unsigned char a, unsigned char b) { |
|||
return ((unsigned char (*) (unsigned char, unsigned char))code)(a, b); |
|||
}</lang> |
|||
<lang scala>// Kotlin Native version 0.3 |
|||
import kotlinx.cinterop.* |
|||
import string.* |
|||
import mman.* |
|||
import mcode.* |
|||
fun main(args: Array<String>) { |
|||
memScoped { |
|||
val bytes = byteArrayOf( |
|||
144 - 256, // Align |
|||
144 - 256, |
|||
106, 12, // Prepare stack |
|||
184 - 256, 7, 0, 0, 0, |
|||
72, 193 - 256, 224 - 256, 32, |
|||
80, |
|||
139 - 256, 68, 36, 4, 3, 68, 36, 8, // Rosetta task code |
|||
76, 137 - 256, 227 - 256, // Get result |
|||
137 - 256, 195 - 256, |
|||
72, 193 - 256, 227 - 256, 4, |
|||
128 - 256, 203 - 256, 2, |
|||
72, 131 - 256, 196 - 256, 16, // Clean up stack |
|||
195 - 256 // Return |
|||
) |
|||
val len = bytes.size |
|||
val code = allocArray<ByteVar>(len) |
|||
for (i in 0 until len) code[i] = bytes[i] |
|||
val buf = mmap(null, len.toLong(), PROT_READ or PROT_WRITE or PROT_EXEC, |
|||
MAP_PRIVATE or MAP_ANON, -1, 0) |
|||
memcpy(buf, code, len.toLong()) |
|||
val a: Byte = 7 |
|||
val b: Byte = 12 |
|||
val c = runMachineCode(buf, a, b) |
|||
munmap(buf, len.toLong()) |
|||
println("$a + $b = ${if(c >= 0) c.toInt() else c + 256}") |
|||
} |
|||
}</lang> |
|||
{{out}} |
|||
<pre> |
|||
7 + 12 = 19 |
|||
</pre> |
|||
=={{header|Nim}}== |
=={{header|Nim}}== |