M68000のポストインクリメント・アドレッシングモードでa7レジスタの場合に2加算になる理由とは?

4
Kazuho Oku @kazuho

68kにはpost-incrementというアドレッシングモードがあり add.l (a0)+,d0 は、アドレスa0から32bit値(”l”ong word)を読みd0に加算、その後a0に4加算、という命令である。 アドレスは命令がadd.w(word)なら2加算、add.b(byte)なら1加算である。 ただし…

2022-04-27 12:25:43
Kazuho Oku @kazuho

レジスタがa7の場合は、add.bの場合も2加算である。 これはなぜか? 考察せよ

2022-04-27 12:25:44
Kazuho Oku @kazuho

Cプログラマに求められるメモリモデルの理解ってこういうやつでしょ? twitter.com/kazuho/status/…

2022-04-27 12:28:48
Kazuho Oku @kazuho

答えがわからなくてもいいけど、理由聞いてそうだよね、ってなるくらいのメモリモデルの理解がないとCプログラマとしては、やっていけないというやつ。 ヒントは twitter.com/ruimo/status/1…

2022-04-27 14:41:23
ruimo @ruimo

ヒント: スタックポインタ

2022-04-27 12:30:28
Kazuho Oku @kazuho

ついでに言うと68kのメモリバスは16bit

2022-04-27 15:25:03
そうは、い観世音菩薩@GPT @iruka3

@kazuho MC68000のa7レジスタのポストインクリメント挙動アノマリー

2022-04-27 15:43:26
あづさ’s @crust09

@kazuho bus 幅が 16bit だから、では不充分なのかな? 要らないことばかり思い出して、気になることが出てきた(では68008は?とか)けど解らない。

2022-04-27 16:49:49
Kazuho Oku @kazuho

@crust09 バス幅が16bitなら、なぜa7だけ特別扱いする必要があるのでしょう?というのが出題意図です

2022-04-27 16:58:35
あづさ’s @crust09

@kazuho 30数年前はゴリゴリでアセンブラ書いてたけど、思い出せない。プログラムカウンタ絡みで、割り込みかかった時の挙動のような気もするが、CP/M 68Kだったから、C側からコールされて使えるのは d0~d2, a0~a2 だったし(言い訳)、帰ったら保存してある書籍見ようと思う。

2022-04-27 17:24:56
Yoshifumi Nishida @nsd

@kazuho @crust09 A7はSPで68KアーキテクチャではSPを8bit加算する操作がないからとか? Z80もPUSH AはなくてPUSH AFしかなかった様な。

2022-04-27 17:47:02
Kazuho Oku @kazuho

@nsd @crust09 そうですね、なぜ他のアドレスレジスタと違いspの加減算だけが16bit単位なのか、というのが聞きたかったところではあります。 68kだと8bitの値をpush popすることはできて、例えば move.b (a0)+,-(a7) は、a7-=2、1バイトの値コピー、a0+=1という操作になります

2022-04-27 18:13:58
Yoshifumi Nishida @nsd

@kazuho @crust09 カンニングしてマニュアル見てみましたが、To keep data on the system stack aligned for maximum efficiencyしか書いてませんでした。。

2022-04-29 17:49:36
だーすー𝕏(Hiroshi Suda) @suda_hiroshi

@kazuho 懐かしいです. 68000だとメモリへのwordとlong word単位のアクセス時に偶数アドレスからしかアクセスできず,a7はスタックポインタであるためlong word単位のアドレスが積まれることがあるから奇数アドレスにならないようになっている. で合っていますでしょうか?(抜けがありそう)

2022-04-27 18:00:07
Kazuho Oku @kazuho

@suda_hiroshi 良いと思います! 細かなツッコミとしては、スタックにはwordを積むことももちろんありますが、理由の説明は完璧かと

2022-04-27 18:32:51
まどちん●牛オーグ @madscient

・a7はスタックポインタである ・割込み(トラップ)が発生すると、必ずスタックにアドレス(32bit)が積まれる ・68kは奇数アドレスからは1バイトの読み書きしかできない(するとアドレスエラーが発生) 以上のことから、スタックポインタが奇数になる瞬間があってはならないことになる。 twitter.com/kazuho/status/…

2022-04-27 19:35:13
真木 修 @mio8801

@madscient そういえば、奇数アドレスからのw/lアクセスは68020で可能になった(ただし遅い)記憶。使ったことないけど。a7の.bはそれでも+2だったんですかね?

2022-04-27 21:41:26
まどちん●牛オーグ @madscient

@mio8801 020以降でもA7のポストインクリメント/プリデクリメントは必ず2ずつですね。

2022-04-27 23:15:11
TcbnErik / 立花@桑島技研 @kg68k

「2加算だと便利なこと」は挙げられても、納得のいく「なぜか」は難しいです…。 スタックから1バイト確保するのにsubq.l #1,spやlink a6,#-1はNGなのだから、同様に1加算で「.bサイズ(sp)+/-(sp)は実行できるがその後アドレスエラーを引き起こすので原則使わない」という扱いでもよかったはずです。 twitter.com/kazuho/status/…

2022-04-27 23:29:12
TcbnErik / 立花@桑島技研 @kg68k

8ビットCPU用アセンブラコードから68000へのトランスレータに都合がよい仮説、XLATE09(画像1枚目)だとa5/a6、Z80CONV(2枚目)でもa6を使っているので否定。 pic.twitter.com/Ry9LnyfC8X

2022-04-29 02:23:16
拡大
拡大
TcbnErik / 立花@桑島技研 @kg68k

設計思想として「(An)は常にデータの先頭を指す」とか「データ転送時は常にフラグに反映する」といったものがあれば、move.b d0,-(sp)の代わりにmove.w d0,-(sp)を使うような手段が却下になり、実現のために2加算用の専用回路を用意するのも当然になりますが、どうでしょう。

2022-04-29 02:38:20
red-dragon @reddrag64988892

@kazuho 奇数アドレスからwordやlong wordのデータを読み書きする場合が起こりえてしまうから、かな?

2022-04-27 23:48:23
Neppo Telewisteria @ 真の美少女 @jo7ueb

スタックポインタで使うから? よくわからんが超便利な機能だなぁ twitter.com/kazuho/status/…

2022-04-28 05:38:17
kame @era_1512

@kazuho はじめまして。 ハードウエア的に2byte境界でしかアクセス(もしくはジャンプ)できないからですかね?

2022-04-28 07:23:42
えぬおう @enuou1000

a7がspで奇数アドレスになるとスタック操作時に即バスエラー例外割り込みが発生してしまうから twitter.com/kazuho/status/…

2022-04-28 07:49:03