読者です 読者をやめる 読者になる 読者になる

by shigemk2

当面は技術的なことしか書かない

MN10300 のまとめ #ikebin

まとめ

パナソニックの32ビットマイコン。

void null()
{
  return;
}

int return_zero()
{
  return 0;
}

戻り値用の変数にd0を使っているのではないか、というあたり。

00fe1400 <_null>:
  fe1400:   f0 fc           rets    

00fe1402 <_return_zero>:
  fe1402:   00              clr d0
  fe1403:   f0 fc           rets    

00fe1405 <_return_one>:
  fe1405:   80 01           mov 1,d0
  fe1407:   f0 fc           rets    

00fe1409 <_return_int_size>:
  fe1409:   80 04           mov 4,d0
  fe140b:   f0 fc           rets    

3バイト命令や6バイト命令

short return_short()
{
  return 0x7788;
}

long return_long()
{
  return 0x778899aa;
}

見てみるとリトルエンディアンで即値を扱っている

00fe1419 <_return_short>:
  fe1419:   2c 88 77        mov 30600,d0
  fe141c:   f0 fc           rets    

00fe141e <_return_long>:
  fe141e:   fc cc aa 99     mov 2005440938,d0
  fe1422:   88 77 
  fe1424:   f0 fc           rets    

MN10300はCISC系であるから、命令バイト数も可変長である。

第三引数はスタックで渡される

int return_arg1(int a)
{
  return a;
}

int return_arg2(int a, int b)
{
  return b;
}

int add(int a, int b)
{
  return a + b;
}

int add3(int a, int b, int c)
{
  return a + b + c;
}
  • d0が第一引数 d1が第二引数
  • 第三引数はスタックポインタ(sp)を使っている
00fe1432 <_return_arg1>:
  fe1432:   f0 fc           rets    

00fe1434 <_return_arg2>:
  fe1434:   84              mov d1,d0
  fe1435:   f0 fc           rets    

00fe1437 <_add>:
  fe1437:   e4              add d1,d0
  fe1438:   f0 fc           rets    

00fe143a <_add3>:
  fe143a:   e1              add d0,d1
  fe143b:   58 0c           mov (12,sp),d0
  fe143d:   e4              add d1,d0
  fe143e:   f0 fc           rets    

アドレスを扱うレジスタが別にある

  • MN10300ではアドレス指定用のレジスタをデータ保持用のレジスタとは別に持っている
  • ので、 move (d0), d0みたいな書き方が出来ない
int load(volatile int *p)
{
  return *p;
}

void store(volatile int *p)
{
  *p = 0xff;
}
00fe1450 <_load>:
  fe1450:   f1 e0           mov d0,a0
  fe1452:   70              mov (a0),d0
  fe1453:   f0 fc           rets    

00fe1455 <_store>:
  fe1455:   f1 e0           mov d0,a0
  fe1457:   2c ff 00        mov 255,d0
  fe145a:   60              mov d0,(a0)
  fe145b:   f0 fc           rets    

代入はすべてmov命令

struct structure {
  int a;
  int b;
  int c;
};

int member(struct structure *p)
{
  p->b = 1;
  return p->c;
}
  • 4つ先にbがあって、8つ先にcがある intは4バイト命令
00fe146d <_member>:
  fe146d:   f1 e0           mov d0,a0
  fe146f:   80 01           mov 1,d0
  fe1471:   f8 10 04        mov d0,(4,a0)
  fe1474:   f8 00 08        mov (8,a0),d0
  fe1477:   f0 fc           rets    

レジスタへの即値代入( 1 バイト値, 2 パイト値, 4 バイト値)

  fe1419:    2c 88 77        mov 30600,d0

レジスタからレジスタへの値のコピー

  fe1450:    f1 e0           mov d0,a0

など。

結構組み込みを意識しているCPUです。

熱血! アセンブラ入門

熱血! アセンブラ入門