Date: Tue, 13 Jun 2023 12:02:41 +0100
[ I tried to put this up on GodBolt and provide a link,
but I gave up on the GNU inline assembler syntax,
I just couldn't get it to work ]
Ever since C++ came out in 1979, there hasn't been any good reason why
the command line arguments to a program cannot be used as arguments to
the constructors of global objects.
I propose that in <cstdlib>, there will be:
namespace std {
extern int argc;
extern char **argv;
}
To implement this in my following example, the entry point to the
program will be 'entrypoint' instead of '_start', and the values of
'argc' and 'argv' will be gotten from the stack. The following syntax
is for the 'nasm' assembler:
extern _ZSt4argc ; mangled name of std::argc (dword = 4 bytes)
extern _ZSt4argv ; mangled name of std::argv (qword = 8 bytes)
extern _start
section .text
global entrypoint:function
entrypoint:
push r15 ; callee-saved (we will restore it later)
add rsp, 8 ; move the stack pointer to argc
mov r15d, dword[rsp]
mov dword[_ZSt4argc], r15d
add rsp, 8 ; move the stack pointer to argv
mov r15, rsp
mov qword[_ZSt4argv], r15
sub rsp, 16 ; move the stack pointer back to where we stored r15
pop r15 ; restore the original value of r15 (callee-saved)
jmp _start
So you compile this assembler as follows:
nasm -o entrypoint.o -f elf64 entrypoint.asm
And then we build our program with:
g++ -o prog main.cpp -no-pie entrypoint.o -e entrypoint
Here's an example program that works:
#include <iostream>
namespace std {
int argc;
char **argv;
}
class LaserController {
int const grade;
char model[16u];
public:
LaserController(int const arg_grade, char const *const arg_model)
: grade(arg_grade)
{
if ( nullptr == arg_model ) { model[0u] = '\0'; return; }
for ( unsigned i = 0u; i < sizeof(model); ++i )
{
model[i] = arg_model[i];
if ( '\0' == model[i] ) break;
}
model[sizeof(model) - 1u] = '\0';
}
void Print(void)
{
std::cout << "Grade: " << grade << ", Model: " << model <<
std::endl;
}
};
LaserController gLaser( std::argc, std::argv[ std::argc - 1u ] );
int main(int argc, char **argv)
{
gLaser.Print();
}
but I gave up on the GNU inline assembler syntax,
I just couldn't get it to work ]
Ever since C++ came out in 1979, there hasn't been any good reason why
the command line arguments to a program cannot be used as arguments to
the constructors of global objects.
I propose that in <cstdlib>, there will be:
namespace std {
extern int argc;
extern char **argv;
}
To implement this in my following example, the entry point to the
program will be 'entrypoint' instead of '_start', and the values of
'argc' and 'argv' will be gotten from the stack. The following syntax
is for the 'nasm' assembler:
extern _ZSt4argc ; mangled name of std::argc (dword = 4 bytes)
extern _ZSt4argv ; mangled name of std::argv (qword = 8 bytes)
extern _start
section .text
global entrypoint:function
entrypoint:
push r15 ; callee-saved (we will restore it later)
add rsp, 8 ; move the stack pointer to argc
mov r15d, dword[rsp]
mov dword[_ZSt4argc], r15d
add rsp, 8 ; move the stack pointer to argv
mov r15, rsp
mov qword[_ZSt4argv], r15
sub rsp, 16 ; move the stack pointer back to where we stored r15
pop r15 ; restore the original value of r15 (callee-saved)
jmp _start
So you compile this assembler as follows:
nasm -o entrypoint.o -f elf64 entrypoint.asm
And then we build our program with:
g++ -o prog main.cpp -no-pie entrypoint.o -e entrypoint
Here's an example program that works:
#include <iostream>
namespace std {
int argc;
char **argv;
}
class LaserController {
int const grade;
char model[16u];
public:
LaserController(int const arg_grade, char const *const arg_model)
: grade(arg_grade)
{
if ( nullptr == arg_model ) { model[0u] = '\0'; return; }
for ( unsigned i = 0u; i < sizeof(model); ++i )
{
model[i] = arg_model[i];
if ( '\0' == model[i] ) break;
}
model[sizeof(model) - 1u] = '\0';
}
void Print(void)
{
std::cout << "Grade: " << grade << ", Model: " << model <<
std::endl;
}
};
LaserController gLaser( std::argc, std::argv[ std::argc - 1u ] );
int main(int argc, char **argv)
{
gLaser.Print();
}
Received on 2023-06-13 11:02:53