View Single Post
Old 06 April 2019, 19:54   #5
alkis
Registered User

 
Join Date: Dec 2010
Location: Athens/Greece
Age: 48
Posts: 508
I don't know if it's possible opening dos library with required version of 0 to ever be able to fail. (Maybe when you don't have any memory left)

If you fail to open it though, you have (at least) two options:
1)
#define THISPROC ((struct Process *)(SysBase->ThisTask))
#define Result2(x) THISPROC->pr_Result2 = x
Result2(ERROR_INVALID_RESIDENT_LIBRARY);

Not very visible to user.

2)
Alert( AG_OpenLib | AO_DOSLib );
Pretty visible to user (with magic numbers with no meaning ofc)


To still be able to "pull" standard functions (like strlen) you can go with -nostartfiles at linking instead of -nostdlib.

Further to make your executable even more clean and mean you could not have any globals at all and allocate them on the heap. (thus having it "pure" and re-entrantable. you can have it resident)

Something like that

Code:
#include <proto/exec.h>
#include <proto/dos.h>
#include <exec/alerts.h>

#include <string.h>

struct globals {
  struct ExecBase *SysBase;
  struct DosLibrary *DOSBase;
  BPTR   Stdout;
};

#define SysBase gv->SysBase
#define DOSBase gv->DOSBase


STATIC const ULONG tricky=0x16c04e75; /* move.b d0,(a3)+ ; rts */
VOID myprintf(struct globals *gv, char *fmt,...) {
  unsigned char buf[256];
  STRPTR *arg = (STRPTR *)(&fmt+1);
  RawDoFmt((STRPTR) fmt, arg, (void (*)())&tricky, buf);
  Write(gv->Stdout, buf, strlen((char *)buf));
}



#undef SysBase
#undef DOSBase
int foo() {
  struct ExecBase *SysBase = (*((struct ExecBase **) 4));
  struct globals *gv;
  

  if (!(gv=AllocMem(sizeof(struct globals), MEMF_ANY))) {
    Alert( AG_NoMemory );
    return 20;
  }

  struct DosLibrary *DOSBase = (struct DosLibrary *)OpenLibrary((STRPTR)"dos.library",33);
  if (!DOSBase) {
    FreeMem(gv, sizeof(struct globals));
    Alert( AG_OpenLib | AO_DOSLib );
    return 20;
  }

  gv->SysBase = SysBase;
  gv->Stdout = Output();
  gv->DOSBase = DOSBase;


  float x = 1.623 * (float) 100;
  myprintf(gv, "Just a hello world. If you cast x to integer is: %ld\n", (int)x);

  FreeMem(gv, sizeof(struct globals));
  CloseLibrary((struct Library *) DOSBase);
  return 0;
}
This compiles to 356 bytes with a custom printf builtin. (it won't do floats though)

Attached you can find a buildable make based sample.
Attached Files
File Type: zip nostartup.zip (1.6 KB, 25 views)
alkis is offline  
 
Page generated in 0.04979 seconds with 12 queries