Created
March 1, 2014 12:08
-
-
Save davidad/9288924 to your computer and use it in GitHub Desktop.
Abusing LuaJIT as a REPL for assembly language
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- warning: this is hacky. run at your own risk. | |
-- | |
-- before you run this, put sum_list.asm in a dynamic library. | |
-- | |
-- on OSX that means | |
-- $ nasm -f macho64 sum_list.asm | |
-- $ libtool -dynamic sum_list.o -o libsum_list.dylib | |
-- | |
-- on Linux it means | |
-- $ nasm -f elf64 sum_list.asm | |
-- $ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:. | |
-- $ ld -shared sum_list.o -o libsum_list.so | |
-- | |
-- when you run it use -i, like so: | |
-- $ luajit -i asmrepl.lua | |
-- this dumps you into LuaJIT's REPL after evaluating the file is done | |
ffi = require("ffi") | |
ffi.cdef[[ | |
struct number_list { | |
uint64_t number; | |
struct number_list *next; | |
}; | |
uint64_t sum_list(struct number_list*); | |
]] | |
asm = ffi.load("sum_list") | |
function sum_list(list) | |
print(tonumber(asm.sum_list(list))) | |
end | |
dont_gc = {} -- such hacky. many bad idea. | |
function from (min,max) | |
function range (min,max,cdr) | |
if max<min then return cdr end | |
dont_gc[max] = ffi.new("struct number_list",{max, cdr}) | |
return range (min,max-1,dont_gc[max]) | |
end | |
return range(min,max,nil) | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
bits 64 | |
; macros for readability | |
%define list rdi ; by calling convention, argument shows up here | |
%define accum rax ; accumulator (literally!) | |
%define sublist rdx | |
global _sum_list ; OSX likes pre-underscores | |
_sum_list: | |
global sum_list ; Linux doesn't | |
sum_list: | |
mov accum, 0 ; these are the let-bindings! | |
mov sublist, list | |
.sum_sublist: | |
cmp sublist, 0 ; is it NULL? | |
jnz .else ; if not, goto else | |
ret; accum (because return value is rax by calling convention) | |
.else: | |
add accum, [sublist] ; accum+=sublist->number; | |
mov sublist, [sublist+8] ; sublist=sublist->next; | |
jmp .sum_sublist |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment