こんにちは。NoMaYです。最近、以下のスレッドに関わったのですが、暫く時間が経った後で思い返してみると、farキーワードの起源の8086のマイクロソフトコンパイラでの仕様とか、CC-RL及びそれに準ずるLLVM-RL78での仕様とか、それらを鑑みると、投稿した以下のコードでの64KB境界を跨いだfarポインタのインクリメントやポインタ比較は素朴に期待したようには動かないのが本来の仕様である可能性が高い筈、と思い直しました。そこで、コードを考え直してみることにしました。続く。C言語からのアセンブラ関数呼び出しについてcommunity-ja.renesas.com/cafe_rene/forums-groups/beginners/f/002-2095199602/9532/c上のスレッドに投稿した、素朴に期待したようには動かないのが本来の仕様である可能性が高い、そんなコード(現状はGNURL78でOKだが):
#include <stdint.h>const uint16_t __far psum_rom = 0x1234; /* This variable is placed at the end of the ROM by linker script. */uint16_t _RomSum(void);uint16_t __attribute__((noinline, optimize("no-isolate-erroneous-paths-dereference"))) _RomSum(void){ // FIXME: In case of using the immediate value in stead of `&psum_rom`, if other than -O0 is used, // the generated code has no ES register handling. It seems to be a bug of GNURL78 (ex. 4.9.2.202201). const uint16_t __far *prom, *sum_s, *sum_e; uint16_t sum = 0; sum_s = 0; sum_e = &psum_rom; // (const uint16_t __far *)0x017DFEUL; --> No ES register handling. for( prom = sum_s; prom < sum_e; prom++ ) { sum += *prom; } return sum;}
こんにちは。NoMaYです。今になって思い至ったのですが、2つ前に書いた以下のことを鑑みると、GNURL78の__farが、桁上がりや桁借りをやらないことによる効率向上よりも、もともとGCCに無かった__farを追加するにあたり開発期間/開発費用を節約する為にいっそのことポインタ演算に関してuint32_tと同じ扱いにしたことによる結果として桁上がりや桁借りもやるようになっていた、という気もしてきました。> 他方、その頃、私はGCCを使っていなかったので、GCCではどういう仕様になっていたのか、というか8086向けGCCはもともと存在しなかったような(曖昧な記憶では80386向けDOSエクステンダ上で動作するDJGPP(DJ Delorie氏が開発)というGCC以前にはx86向けのものは存在しなかったような)気もしますが、私はそのあたりのことが分かりません。> そして、GCCのドキュメントには、現在のx86向けのGCCに関してはnear/far/hugeというキーワードは存在しないようでした。そこで、以下のソースをコンパイルしてリストファイルを眺めてみたところ、これは確かにそういうことだよなぁ、という結論に至りました。ということで、このスレッドは私の勘違いでした、ということで終わりにします。すみません。了ソース:
uint16_t __far *ptr;void test(void){ ptr++;}
-O0でのリストファイル:
0000 AF 00 00 movw ax, !_ptr 0003 BD F0 movw r8, ax 0005 AF 00 00 movw ax, !_ptr+2 0008 BD F2 movw r10, ax 000a AD F0 movw ax, r8 000c 04 02 00 addw ax, #2 000f BD F0 movw r8, ax 0011 AD F2 movw ax, r10 0013 61 D8 sknc 0015 A1 incw ax 0016 BD F2 movw r10,ax 0018 AD F0 movw ax, r8 001a BF 00 00 movw !_ptr, ax 001d AD F2 movw ax, r10 001f BF 00 00 movw !_ptr+2, ax 0022 D7 ret
-O1,-O2,-O3,-Os,-Ogでのリストファイル:
0000 AF 00 00 movw ax, !_ptr 0003 04 02 00 addw ax, #2 0006 BF 00 00 movw !_ptr, ax 0009 AF 00 00 movw ax, !_ptr+2 000c 61 D8 sknc 000e A1 incw ax 000f BF 00 00 movw !_ptr+2,ax 0012 D7 ret