Call a foreign-language function: Difference between revisions
Content added Content deleted
No edit summary |
|||
Line 2,744: | Line 2,744: | ||
Hello World! |
Hello World! |
||
</pre> |
</pre> |
||
=={{header|X86-64 Assembly}}== |
|||
===UASM 2.52=== |
|||
Calling C functions in Assembly is trivial at best. It's not anymore complicated than using them in C itself. Strdup for example.. |
|||
<lang asm> |
|||
option casemap:none |
|||
strdup proto :qword |
|||
printf proto :qword, :vararg |
|||
exit proto :dword |
|||
.data |
|||
bstr db "String 1",0 |
|||
.data? |
|||
buff dq ? |
|||
.code |
|||
main proc |
|||
invoke printf, CSTR("Copying %s to buff with strdup using invoke....",10), addr bstr |
|||
invoke strdup, addr bstr |
|||
mov buff, rax |
|||
invoke printf, CSTR("buff now = %s",10), buff |
|||
invoke exit, 0 |
|||
ret |
|||
main endp |
|||
end |
|||
;Now, we could target a specific ABI by assigning the call values to the registers like |
|||
;.code |
|||
;main proc |
|||
; lea rdi, bstr |
|||
; call strdup |
|||
; mov buff, rax |
|||
;main endp |
|||
;end |
|||
</lang> |
|||
but that's not very fun. So let's run some lua script insted. |
|||
<lang asm> |
|||
option casemap:none |
|||
option literals:on |
|||
windows64 equ 1 |
|||
linux64 equ 3 |
|||
ifndef __LUA_CLASS__ |
|||
__LUA_CLASS__ equ 1 |
|||
LUA_OK equ 0 |
|||
if @Platform eq windows64 |
|||
option dllimport:<kernel32> |
|||
GetProcessHeap proto |
|||
ExitProcess proto :dword |
|||
HeapAlloc proto :qword, :dword, :qword |
|||
HeapFree proto :qword, :dword, :qword |
|||
option dllimport:none |
|||
exit equ ExitProcess |
|||
elseif @Platform eq linux64 |
|||
malloc proto SYSTEMV :qword |
|||
free proto SYSTEMV :qword |
|||
endif |
|||
printf proto :qword, :vararg |
|||
exit proto :dword |
|||
;; Lua.h funcs |
|||
luaL_newstate proto ;; lua_State *luaL_newstate(); |
|||
lua_gettop proto :qword ;; int lua_getopt(lua_State *L); |
|||
lua_close proto :qword ;; void lua_close(lua_State *L); |
|||
luaL_openlibs proto :qword ;; int luaL_openlibs(lua_State *L); |
|||
lua_settop proto :qword, :dword ;; int lua_setopt(lua_State *L, int idx) |
|||
luaL_loadstring proto :qword, :qword ;; int luaL_loadstring(lua_state *L, char *string); |
|||
lua_pcallk proto :qword, :dword, :dword, :dword, :dword, :dword |
|||
CLASS lua_class |
|||
CMETHOD runstr |
|||
ENDMETHODS |
|||
lua_state qword 0 |
|||
ENDCLASS |
|||
METHOD lua_class, Init, <VOIDARG>, <> |
|||
mov rbx, thisPtr |
|||
assume rbx:ptr lua_class |
|||
invoke luaL_newstate |
|||
mov [rbx].lua_state, rax |
|||
invoke luaL_openlibs, [rbx].lua_state |
|||
.if rax != LUA_OK |
|||
invoke printf, CSTR("---> Lua failed to open libs",10) |
|||
jmp _ext |
|||
.endif |
|||
_ext: |
|||
mov rax, rbx |
|||
assume rbx:nothing |
|||
ret |
|||
ENDMETHOD |
|||
METHOD lua_class, runstr, <VOIDARG>, <>, s:qword |
|||
local tmp:qword |
|||
mov rbx, thisPtr |
|||
assume rbx:ptr lua_class |
|||
mov rax, s |
|||
mov tmp, rax |
|||
invoke luaL_loadstring, [rbx].lua_state, tmp |
|||
invoke lua_pcallk, [rbx].lua_state, 0, 0, 0, 0, 0 |
|||
.if rax != LUA_OK |
|||
invoke printf, CSTR("--> luaL_pcallk failed with %i",10), rax |
|||
.else |
|||
invoke lua_gettop, [rbx].lua_state |
|||
not eax |
|||
invoke lua_settop, [rbx].lua_state, eax |
|||
.endif |
|||
mov rax, 0 |
|||
assume rbx:nothing |
|||
ret |
|||
ENDMETHOD |
|||
METHOD lua_class, Destroy, <VOIDARG>, <> |
|||
mov rbx, thisPtr |
|||
assume rbx:ptr lua_class |
|||
.if [rbx].lua_state != 0 |
|||
invoke lua_close, [rbx].lua_state |
|||
.endif |
|||
assume rbx:nothing |
|||
ret |
|||
ENDMETHOD |
|||
endif ;__LUA_CLASS__ |
|||
.code |
|||
main proc |
|||
local lvm:ptr lua_class |
|||
invoke printf, CSTR("-> Attempting to init Lua...",10) |
|||
mov lvm, _NEW(lua_class) |
|||
invoke printf, CSTR("-> Lua started, Running first test..",10) |
|||
lvm->runstr(CSTR("print('Goodbye, world from Lua..')")) |
|||
.if rax != LUA_OK |
|||
invoke printf, CSTR("-> Runstring failed, exiting...",10) |
|||
jmp _ext |
|||
.endif |
|||
_ext: |
|||
_DELETE(lvm) |
|||
mov rax, 0 |
|||
invoke exit, 0 |
|||
main endp |
|||
end |
|||
</lang> |
|||
{{out}} |
|||
<pre> |
|||
-> Attempting to init Lua... |
|||
-> Lua started, Running first test.. |
|||
Goodbye, world from Lua.. |
|||
</pre> |
|||
When I stop being lazy and/or drunk, I'll update the class to run a lua script file... |
|||
=={{header|zkl}}== |
=={{header|zkl}}== |