★ FAQ ★ Development environment ★ GNU development environment> 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
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 is known to return incorrect results when optimizing non-volatile inline assemblers.
Also, if you forget the two colons that separate the register constraints at the end of the inline assembler fragment, GCC usually crashes. Be sure to add two colons even if the inline assembler does not have a register constraint.
GCC allows you to put the inline assembler section outside the function, so you can create a routine written entirely in assembler in the C source.
Ignore the "volatile" keyword when using assemblies outside of C functions as it only misleads the compiler.
* Inline assembler written outside the function in C source cannot be debugged at the source level. --If you want to write large size assembly code, it is recommended to create a separate assembly file.
This will probably result in correct debugging at the source level.
/ *
** 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; \
});
![]() | Using a divider is extremely dangerous because it uses MAC registers. |
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:
::
Error message appears.
★ FAQ ★ Development environment ★ GNU development environment