ユーザーmalloc

malloc というのはメモリーを動的に確保するための関数です。一般のアプリケーションは動的にメモリ中に読み込まれるため(つまり毎回メモリの番地が変わるため)、その中でメモリーを動的に確保するためにはアプリケーション用の malloc を作らなければなりません。はりぼてOS のソースコードを見るとなんと最大 32KB 固定の手抜き仕様っぽかったので、自分で実装してみました。動的確保開始アドレスと終了アドレスを指定するだけで、OSメモリ管理用のメモリマネージャがそのまま使えたため、追加した行数はわずか12行です。

ちなみに、一般のアプリケーションは、終了したら malloc で使った領域ともども開放されるため、free を忘れても大丈夫なんですね(笑)。

void Console::parseCommand() 内(OS側)

      int malloc_start = *((int *) (code + 0x0020));
            :
      current->memory  = new Memory();
      current->memory->init((dword) &data[malloc_start], (dword) &data[seg_size - 1]);
            :
      delete(current->memory);

システムコール内(OS側)

  else if (func_num == API_MALLOC) {
    void* addr = current->memory->allocate(arg1);
    reg[7] = ((int) addr) - ds_base;
  }

  else if (func_num == API_FREE) {
    dword* addr = (dword *) arg1 + ds_base;
    current->memory->free(addr);
  }

api_malloc.cpp(アプリケーション側)

#include "syscall.h"

unsigned int api_malloc(int size)
{
  unsigned int result;
  SYSCALL_1(API_MALLOC, result, size);
  return result;
}

api_free.cpp(アプリケーション側)

#include "syscall.h"

void api_free(void* addr)
{
  unsigned int result;
  SYSCALL_1(API_FREE, result, addr);
}

catもどきアプリケーション

#include "../apilib/syscall.h"

extern "C" {
  void HariMain(void);
}

void HariMain(void)
{
  int file = api_fopen("license.txt");
  int size = api_fsize(file /* handle */, 0 /* mode */);
  char* buff = (char *) api_malloc(size + 1);
  api_fread(buff, size, file);
  buff[size] = '\0';
  api_putstr0(buff);
  api_fclose(file);
  api_free(buff);
  api_end();
}