What's the meaning of __saveds in Amiga C code?

It's applied to function prototypes, and is required for functions that are to be called by assembler code, if I understand correctly.

up vote 11 down vote accepted

What it does

Quoting from the SAS/C© Development System User's Guide, arguably the authoritative source for Amiga C code:

If you define a function with the __saveds keyword, the compiler generates extra code at the beginning of the function that loads the address of the near data section into register A4. Defining a function with the __saveds keyword is equivalent to compiling that function with the saveds compiler option.

The extra code would typically look something like this:

        ...
        LEA     _LinkerDB,A4
        ...

_LinkerDB is a symbol supplied by the linker, and points to the Near Data section.

Near Data section

The compiler tries to fit everything in this section, but it's limited to 64 KiB[1]. This limit means that it can be addressed using a shorter and faster 16-bit addressing mode. Another quote from the SAS/C manual:

When you link your program, all data in the near data and near BSS hunks are merged into one near data section. When you run your program, the startup module loads the address of the near data section into register A4, and this section is referenced with 16-bit A4-relative addresses.

Not only are the instructions shorter, but they don't need an entry in the relocation table, so it makes the executable file even smaller.

Why it is needed

The key point here is that the startup module initializes A4, and the rest of the compiled code never touches it again. In "normal" code, you don't have to think about this. However, that "normal" code will expect A4 to point to the location of the data. If not, every single function would have to load the pointer, which would mostly negate the benefits of having one globally.

Thus, there are a few cases where you have to initialize it manually:

  • You have no startup module. You may want to write a custom startup module but still have everything else work as expected. Your startup module then typically needs __saveds once, and then it doesn't have to be touched again.
  • You are writing C routines to be called externally. In this case, either the caller or your routine has to set up the near data pointer.

[1]: Sometimes 32 KiB depending on the linker. Some linkers did not allow the full range to be used.

This is to make sure that the compiler generates code that loads the near data pointer in register a4 on each function entry so that your function is able to access its data. (source)

Your Answer

 
discard

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.