[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Variable length arguments in C/C++
- From: Sean Conner <sean@...>
- Date: Tue, 9 Aug 2022 02:32:08 -0400
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