lua-users home
lua-l archive

Re: Variable length arguments in C/C++

[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

AltStyle によって変換されたページ (->オリジナル) /