lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


It was thus said that the Great Jairo A. del Rio once stated:
> El lun, 8 ago 2022 a la(s) 14:07, Sean Conner (sean@conman.org) escribió:
> 
> > Now, it's not impossible to do what you are asking for, but it can't be
> > done in C.  No, you'll need to drop down to assembly language [2] if you
> > really want to go this route.  Assembly will give you the control needed to
> > set up the stack (and/or registers) needed to make the call.  But this
> > approach is, by its very nature, very CPU and OS dependent.
> 
> So... no portable solutions out there? 

  Nope.

> I don't know assembly at all, but I guess I'll have to learn about it.

  You have some work cut out for you.
  
> > [2]     Yes, I have written a Lua module in assembly.  It's not hard (if
> >         you know assembly), just tedious.
> 
> I'd like to see that. Thank you very much.

  Sure.  Here's the code:

;***************************************************************************
;
; Copyright 2020 by Sean Conner.
;
; This library is free software; you can redistribute it and/or modify it
; under the terms of the GNU Lesser General Public License as published by
; the Free Software Foundation; either version 3 of the License, or (at your
; option) any later version.
;
; This library is distributed in the hope that it will be useful, but
; WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
; License for more details.
;
; You should have received a copy of the GNU Lesser General Public License
; along with this library; if not, see <http://www.gnu.org/licenses/>.
;
; Comments, questions and criticisms can be sent to: sean@conman.org
;
;***************************************************************************

                bits    32
                global  luaopen_rdtsc
                extern  lua_pushinteger
                extern  lua_pushcclosure

;***************************************************************************
                section .text

ldl_rdtsc:      rdtsc                           ; read time-stamp counter
                push    edx			; lua_pushinteger(L,rdtsc);
                push    eax
                push    dword [esp + 12]
                call    lua_pushinteger
                xor     eax,eax			; return 1;
                inc     eax
                lea     esp,[esp + 12]
                ret

;---------------------------------------------------------------------------

luaopen_rdtsc:
                xor     eax,eax			; lua_pushclosure(L,ldl_rdtsc,0);
                push    eax
                push    ldl_rdtsc
                push    dword [esp + 12]
                call    lua_pushcclosure
                xor     eax,eax			; return 1;
                inc     eax
                lea     esp,[esp + 12]
                ret

;***************************************************************************

  Now, some commentary.  This is for the Intel x86-32 bit architecture,
written for use under Linux, and assembled using nasm (Netwide Assembler). 
The intent of this is to wrap the RDTSC (Read Time-Stamp Counter)
instruction and expose the value to Lua (this code works as I have tested
it).  The x86-64 bit version would look something like (untested code here);

;***************************************************************************
;	LGPL3+
;	code is untested---use at your own risk

		bits	64
		global	luaopen_rdtsc
		extern	lua_pushinteger
		extern	lua_pushclosure

;***************************************************************************
		section	.text

ldl_rdtsc:	rdtsc				; read time-stamp counter
		shl	rdx,32			; lua_pushinteger(L,rdtsc);
		or	rdx,rax			; ??? unsure if upper 32-bits
		mov	rsi,rdx			; of RAX are 0
		call	lua_pushinteger
		xor	rax,rax			; return 1;
		inc	rax
		ret

;---------------------------------------------------------------------------

luaopen_rdtsc:
		mov	rsi,ldl_rdtsc		; lua_pushclosure(L,ldl_rdtsc,0);
		xor	rdx,rdx
		call	lua_pushclosure
		xor	rax,rax			; return 1;
		inc	rax
		ret

;***************************************************************************

  Not only are some of the register names different, but the calling
convention is different between x86-32 bit (parameters passed on the system
stack) and x86-64 bit (first six parameters passed in registers, rest on the
system stack---fun time for your code to support calling variable parameter
functions on x86-64) systems on Linux.

  An in-depth discussion of each instruction is definitley off-topic for
this mailing list---I'm just posting this code here just to show that it is
indeed possible to write a Lua module in assembly (and for a taste in what
you are possibly getting yourself into).

  -spc