* * * * *
A Lua module in assembly, why not?
I've been known to dabble in assembly language from time to time, and there's
been this one instruction on the Intel Pentium that I've wanted to play
around with—RDTSC (Read Time-Stamp Counter). It's used to read the internal
time-stamp counter which is incremented every clock cycle. On my system, this
counter is incremented 2,660,000,000 times per second (the computer is
running at 2.66GHz (Gigahertz)) and this makes for a nice way to time code,
as the instruction is available in userspace (at least on Linux).
I wanted to use this to time some Lua code [1], which means I need to wrap
this instruction into a function that can be called. I could have used some
inline assembly in C to do this, but
1. the code is non-portable anyway;
2. I wanted to avoid as much C overhead as possible;
3. and I thought it would be amusing to write an entire Lua module in
assembly.
It wasn't hard:
-----[ Assembly ]-----
;***************************************************************************
;
; 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:
[email protected]
;
;***************************************************************************
bits 32
global luaopen_rdtsc
extern lua_pushinteger
extern lua_pushcclosure
;***************************************************************************
section .text
ldl_rdtsc: rdtsc
push edx
push eax
push dword [esp + 12]
call lua_pushinteger ; lua_pushinteger(L,rdtsc);
xor eax,eax ; return 1
inc eax
lea esp,[esp + 12]
ret
;---------------------------------------------------------------------------
luaopen_rdtsc:
xor eax,eax
push eax
push ldl_rdtsc
push dword [esp + 12]
call lua_pushcclosure ; lua_pushcclosure(L,ldl_rdtsc,0);
xor eax,eax ; return 1
inc eax
lea esp,[esp + 12]
ret
-----[ END OF LINE ]-----
I'll leave it up to the reader to convert this to 64-bit code.
[1]
gopher://gopher.conman.org/0Phlog:2020/06/05.1
Email author at
[email protected]