I've been working on this program all night. I happened to see a Youtube video about self-changing code and said it was a bad idea, so I decided I'd try doing it myself, in assembly of course. After a few hours, I actually got it working, albeit with hard-coded numbers. It's nothing extravagant, just a proof of concept. It takes two values, now called val1 and val2, adds them, and prints the result to the screen. However, if val1 is greater than val2, it actually changes the opcode for add to sub. Again, I had it working with the values hard-coded and just recompiling every time I wanted to change them.
But while I'm not going all out on this project, I would at least like to get the numbers from the user so it's easy to see it works by typing different numbers instead of having to recompile. I got the printf function working no problem, but try as I may, I couldn't get scanf to work at all. It segfaulted every time I got to it. I considered that maybe it's because there are many different forms of scanf depending on the parameters and the parameters aren't so clearly defined in assembly as in C, so I changed my methodology a bit. I decided to make a separate C routine for getting the two values, and maybe more later to make printing them less messy.
At this point, I've made the function and it can see val1 and val2, it compiles, my function gets called from the main routine composed of assembly, but just as before, it segfaults at scanf. After about six hours of working on this and missing a lot of sleep, I'm finally throwing in the towel for tonight. But of course first I have to show you what I have. Here is the simple C routine I made to get the numbers.
#include <stdio.h>
extern long int val1;
extern long int val2;
void get_values() {
printf("Enter two integers:\n");
scanf("%ld", &val1);
scanf("%ld", &val2);
return;
}
If that's not enough, here's the head of my assembly file. I'll show the whole thing if I can get this working and there's interest.
.global main
.global val1
.global val2
.bss
.lcomm val1, 8
.lcomm val2, 8
(And an example of how I called scanf from the assembly routine)
.text
movq $scanf_identifier_string, %edi
movq $val1, %esi
call scanf
I feel like this should be so simple, yet it has me completely buffaloed. I was really excited that I managed to make a program that overwrites its own instructions dynamically, but a bit embarrassed that I can't get scanf to work. I appreciate any help with this.