The assembler can say where everything ended up

-S writes every label and the address it was given, in address order.

Nothing else knows that. A program on the disk is bytes; the monitor can
disassemble it but has no idea what any of it is called. So counting which
addresses a program calls says a great deal and names nothing - the answer
arrives as a column of numbers and somebody works out by hand which routine
each one is inside.

It was deferred when the native assembler was planned, as a listing and symbol
dump nobody needed yet. Finding out where the assembler spends its time is what
needed it: the top six call targets were addresses until this existed and are
numStep, numCompare, tokGet, srcNext, numAddByte and clsSameName with it.

Sorted by address rather than by name, because the question asked of it is
always "what is at this address".

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E2JrLzFvuFX9fgi1LDRjrW
This commit is contained in:
Anachronaut
2026-08-25 18:15:50 -04:00
co-authored by Claude Opus 5
parent af0360128b
commit 19ab36a201
4 changed files with 64 additions and 1 deletions
+42
View File
@@ -21,6 +21,48 @@ int debugSecondPass = 0;
Label labelArray[MAX_LABELS];
int labelCount = 0;
// ---- Where everything ended up ----
//
// Every label and the address it was given, in address order. The assembler knows this and
// nothing else does: a program on the disk is bytes, and the machine's own monitor can
// disassemble it but has no idea what any of it is called.
//
// WHAT IT IS FOR is telling where a program spends its time. Counting which addresses get
// called says a great deal and names nothing, so the answer arrives as a list of numbers
// and somebody has to work out by hand which routine each one is inside. With this, a
// tally of call targets becomes a list of routine names.
//
// Sorted by address rather than by name, because the question asked of it is always "what
// is at this address", and a label table is small enough that sorting it is free.
static int byAddress(const void *left, const void *right) {
const Label *a = left, *b = right;
if (a->address != b->address) {
return a->address < b->address ? -1 : 1;
}
return strcmp(a->label, b->label);
}
void writeSymbolFile(const char *path) {
FILE *file = fopen(path, "w");
if (!file) {
fprintf(stderr, RED "Error: Could not open file \"%s\" for writing.\n" RESET, path);
exit(1);
}
Label *sorted = malloc((size_t)labelCount * sizeof(Label));
if (!sorted) {
fprintf(stderr, RED "Error: Out of memory writing the symbol file.\n" RESET);
fclose(file);
exit(1);
}
memcpy(sorted, labelArray, (size_t)labelCount * sizeof(Label));
qsort(sorted, (size_t)labelCount, sizeof(Label), byAddress);
for (int i = 0; i < labelCount; i++) {
fprintf(file, "%04X %s\n", sorted[i].address, sorted[i].label);
}
free(sorted);
fclose(file);
}
void freeLabelList() {
for (int i = 0; i < labelCount; i++) {
if (labelArray[i].label) {