neilsf / xc-basic3

A BASIC cross compiler for MOS 6502-based machines
MIT License
45 stars 5 forks source link

Unused subroutines/functions use variable memory #274

Open kochs-online opened 3 months ago

kochs-online commented 3 months ago

This is related to issue #2, I think: I noticed that unused subroutines and functions are reserving memory for their variables, arguments and return values.

Consider the following program:

SUB never_called (s AS STRING * 40) STATIC
END SUB

FUNCTION never_called_2 AS STRING * 20 () STATIC
  RETURN never_called_2
END FUNCTION

DIM a AS BYTE

a = 42

The compiler shows these segments:

+---------------+-------+-------+
|    Segment    | Start |  End  |
+---------------+-------+-------+
|BASIC Loader   | $0401 | $040C |
|Program code   | $040D | $0429 |
|Library        | $042A | $042A |
+---------------+-------+-------+

After completion of issue #2 we would expect the variables segment to use only a single byte of RAM for a, right?

But instead it shows:

+---------------+-------+-------+
|    Segment    | Start |  End  |
+---------------+-------+-------+
|Variables*     | $042B | $046B |
+---------------+-------+-------+

This might be dismissed as being "only a compiler calculation of expected memory usage", but looking at the (relevant part of the) disassembled program you can see that a is getting pushed back in memory by the unused argument/return value. Instead of $042B it is now located at $046B:

lda #2a
sta $046b

So this might lead to situations where a program is running out of memory without really using all of it.

Bonus question: ~~Argument s of subroutine never_called() is using 41 bytes ($042B - $0455) which is to be expected for a 40 character string (incl. its preceding length byte), but the return value of function never_called_2() is only reserving 15 bytes of memory ($0456 - $046B) although being defined as a 20 character string. What is going on there? (I just noticed that the QBASIC style of returning a value is slightly different and not using keyword RETURN, but still…)~~

Edit: D'oh! Of course $0456 - $046B are [decimal] 21 bytes (or [hexadecimal] #$15). So everything is fine there.