Machine code: Difference between revisions

Added Kotlin
m (added pure ilASM example)
(Added Kotlin)
Line 172:
{{out}}
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}}==
9,490

edits