console.c static void printint(int xx, int base, int sign)

トップページ
jupiteroak.hatenablog.com


console.c
https://github.com/mit-pdos/xv6-public/blob/master/console.c#L27

static void printint(int xx, int base, int sign)
{
  static char digits[] = "0123456789abcdef";
  char buf[16];
  int i;
  uint x;

  if(sign && (sign = xx < 0))
    x = -xx;
  else
    x = xx;

  i = 0;
  do{
    buf[i++] = digits[x % base];
  }while((x /= base) != 0);

  if(sign)
    buf[i++] = '-';

  while(--i >= 0)
    consputc(buf[i]);
}

printint関数は、引数baseが指定する進数と引数signが指定する符号属性に基づいて、引数xxが指定する数値を画面に表示します。

引数 int xx
画面に表示させる数値を指定します。

引数 int base
画面に表示させる数値の進数を指定します。
10進数で表示する場合は10を、16進数で表示する場合は16を、指定します。

引数 int sign
画面に表示させる数値の符号属性を指定します。
符号つきの数値として扱う場合は1を、符号なしの数値として扱う場合は0を、指定します。


処理の内容

符号属性に応じた処理を行う

if(sign && (sign = xx < 0))
    x = -xx;
  else
    x = xx;

sign && (sign = xx < 0)が真となる場合→符号付きフラグがセットされ、かつ、xxが負の値である場合は、数値の符号を反転させます。
また、条件式 xx < 0 の結果をsignに保存しておきます。

最下位の桁から順番に進数変換を行う

  i = 0;
  do{
    buf[i++] = digits[x % base];
  }while((x /= base) != 0);

数値xの最下位の桁から進数変換を行い、その結果を配列buffの先頭から格納していきます。
数値xをbaseで剰余演算することにより、base進数における最下位桁の値x % baseを取得することができます。
また、配列digitsを用いてx % baseに対応する数字を取得し、それを配列buffに格納します。
最後に、数値xをbaseで除算することにより、base進数において1桁下げた値を取得します。

負の数の場合は'-'を付加する

if(sign)
    buf[i++] = '-';

xxが負の値だった場合は、buffに記号'-'を追加します。

数値を画面に表示する

while(--i >= 0)
    consputc(buf[i])

配列buffの後方から要素を取り出しconsputc関数を呼び出す処理を繰り返すことで、進数変換後の値を画面に表示させます。