> C:¥SGL¥SAMPLE¥S_2_2>make > ld -Tsl.lnk -oformat srec -Map sl.map -e ___Start main.o polygon.o > ../../lib/libsgl.a ../../lib/libgcc.a -o sl.s > go32 version 1.12.maint1 Copyright (C) 1994 DJ Delorie > Error:This program requires a version of go32(1.12.maint2) newer than > this one. > make.exe: *** [sl.s] Error 1
使っているgo32.exeのバージョンが古い。
Windows95のDOS窓を使っている場合には、プロパティの設定によってはこのような症状の出る可能性があります。
c:/gccsh/bin/../lib/libgcc.a(__main.o): In function `__do_global_dtors': libgcc2.c(.text+0x2c): undefined reference to `__dtors' libgcc2.c(.text+0x30): undefined reference to `__dtors_end' c:/gccsh/bin/../lib/libgcc.a(__main.o): In function `__do_global_ctors': libgcc2.c(.text+0x68): undefined reference to `__ctors_end' libgcc2.c(.text+0x6c): undefined reference to `__ctors' make.exe: *** [mltest.cof] Error 1
gcc driver version cygnus-2.7-96q1 SOA-960328 executing gcc version cygnus-2.7-96q1
.tors ALIGN(0x10) : { ___ctors = . ; *(.ctors) ___ctors_end = . ; ___dtors = . ; *(.dtors) ___dtors_end = . ; }
char stack[10000] __attribute__ ((section ("STACK"))); int flag __attribute__ ((section ("COMMON"))) = 10; void ExpandData( void ) __attribute__ ((section ("Overlay")));
GCC は volatile でないインラインアセンブラをオプティマイズした際に間違った結果を返すことが知られています。
また、もしインライン アセンブラのフラグメントの最後で、レジスタコンストレイント (resister constraints) を分ける二つのコロンを忘れると、
GCC は通常クラッシュします。もしインライン アセンブラにレジスターコンストレイントが無くても、必ずコロンを二つ付けるようにしてください。
GCCはインラインアセンブラセクションをファンクションの外にも置く事が出来るので、全てをアセンブラで書いたルーチンを Cソースの中に作ることが可能です。
Cの関数外でアセンブリを使う時には "volatile" キーワードはコンパイラを惑わすだけなので無視してください。
※ C ソースの中の関数外に書かれたインラインアセンブラはソースレベルでのデバッグは出来ません。- もし大きなサイズのアセンブリコードを
書きたい時には、アセンブリのファイルを別に作ることをお薦めします。
これによって恐らくソース レベルでのデバッグが正しく行われます。
/* ** void Set_Hardware_Divide(int, int); ** ** Set the dividend and divisor of the hardware divide unit. ** The divider requires 37 clocks to calculate a result, ** so you want to execute some other code before retrieving the result. */ #define Set_Hardware_Divide(x,y) ¥ ({ ¥ int *div_unit = (int *)0xffffff00; ¥ int dividend = x, divisor = y; ¥ __asm__ volatile ("mov.l %0,@(4,%2); mov.l %1,@%2" ¥ : /* no output */ ¥ : "r" (dividend), "r" (divisor), "r" (div_unit)); ¥ }); /* ** int Get_Hardware_Divide(void) ** ** Retrieves division result from the hardware divide unit. ** If less than 37 clocks have elapsed the CPU will be halted ** until the result is ready. */ #define Get_Hardware_Divide() ¥ ({ ¥ int *div_unit = (int *)0xffffff00; ¥ int __result; ¥ __asm__ volatile ("mov.l @(0x1c,%1),%0" ¥ : "=r" (__result) ¥ : "r" (div_unit)); ¥ __result; ¥ });
除算器の使用は、MACレジスタを使用するため非常に危険が伴います。 |
int main(void) { cout << "hello, world"; }
temp[index++] = a; temp[index++] = b; temp[index++] = c;
temp[index] = a; temp[index+1] = b; temp[index+2] = c; index += 3;
mov.l L2,r1 mov.l @r1,r1
gcc -g -O -Wa,-ahl main.c : 19:main.c **** j = 0xf000; 77 004c D10E mov.l L10,r1 78 004e 9215 mov.w L14,r2 79 0050 2121 mov.w r2,@r1 21:main.c **** } else { 81 0052 A003 bra L4 82 0054 0009 nop 83 L6: :
というエラーメッセージが出る。