Вы находитесь на странице: 1из 8

The man page for gcc states

file.s
Assembler code.
file.S
file.sx
Assembler code that must be preprocessed.
And many standard include files have
#ifndef __ASSEMBLY__
...
#endif
wrappers to allow inclusion from assembly files. I could have sworn I've written programs before
with gcc and it defined this when assembling, but now I'm running into problems.
Here's some test code:
test.S
#include <sys/syscall.h>
#include <asm/signal.h>
.intel_syntax noprefix
.text
.global foo // int foo(int pid)
foo:
mov esi,SIGUSR1
mov eax,SYS_kill
syscall
ret
When I run gcc -c test.S, it complains about all kinds of stuff in the asm/signal.h because it doesn't
see __ASSEMBLY__ defined.
For now my work around is:
#ifndef __ASSEMBLY__
#define __ASSEMBLY__
#endif
But this just seems wrong to have to add this to all my files.
Is this a bug in GCC? Or am I doing something wrong here?
NOTE:
I see in a test that gcc does define __ASSEMBLER__ but most of the header files test for __ASS
EMBLY__ (I do see a couple that test for __ASSEMBLER__). Was the appropriate ifdef changed
at some point?

Run gcc -dM -E - < /dev/null or even echo > empty.S; gcc -dM -E empty.S to understand which
preprocessor symbols are predefined by your compiler.

I already know the symbol is not defined. I ran your second test, and it confirmed this. This seems
like a bug if gcc is defining _ASSEMBLER_ but the standard headers are checking for _ASSE
MBLY_.
You could define it yourself on the gcc comand line, with -Wa,--defsym,_ASSEMBLY_=1
_ASSEMBLY_ is a convention that the Linux kernel project made up themselves before they
knew about the existence of the gcc predefined macro _ASSEMBLER_.
The linux kernel passes down _ASSEMBLY_ explicitly in linux/Makefile:
KBUILD_AFLAGS := -D_ASSEMBLY_

There were patches posted on LKML to migrate to _ASSEMBLER_ in 2005 but they were not
merged

If you use the GNU toolchain, gcc will by default run the preprocessor on files with the .S
extension (uppercase 'S'). So you can use all cpp features in your assembly file.
There are some caveats:
a) There might be differences in the way the assembler and the preprocessor tokenize the input.
b) If you #include header files, they should only contain preprocessor directives, not C stuff like
function prototypes.
c) You shouldn't use # comments, as they would be interpreted by the preprocessor.
Example:
File definitions.h
#define REGPARM 1
File asm.S
#include "definitions.h"
.text
.globl relocate
.align 16
.type relocate,@function
relocate:
#if !REGPARM
movl 4(%esp),%eax
#endif
subl %ecx,%ecx
...

Even if you don't use gcc, you might be able to use the same approach, as long as the syntax of
your assembler is reasonably compatible with the C preprocessor (see caveats above). Most C com
pilers have an option to only preprocess the input file (e.g. -E in gcc) or you might have the prepro
cessor as a separate executable. You can probably include this preprocessing prior to assembly in
your build tool.
You can't, unless a specific development chain allows it. But in 20 years or so of embedded progr
amming I never saw one.
Usually, the only way for assembly and C to communicate is the linker, i.e. labels defined in C/C
++ are accessable from within assembly (and vice versa).
When I had to share definitions between C/C++ and asm, I usually did it with a custom code gene
rator.
Since high-level data are rarely exchanged with assembly, a few defines and maybe some external
references are usually enough, and thus the code generator is really easy to make.
You can use for instance perl or awk to parse a very simple list of common constants and produce
a pair of files, one with #defines and the other with the equivalent EQU directives.

I'm trying to use a #define value from a C header file in my boot assembly file.
For example, say I have "#define VERSION 0x01020304" in file version.h.
In boot.s I'd like to use ".word VERSION" to place the version constant at a specific location.
To begin with I have boot.s and everything compiles successfully. When I rename boot.s to boot.S
(to enable preprocessing on the assembly file) and attempt to complile, I get a warning from the
linker "warning:
cannot find entry symbol _reset_handler; not setting start address".
Why is the preprocessor interfering with the linker finding _reset_handler in boot.S?
Also, if I attempt to call routines defined in the boot.S file from a .c file they are not found when
preprocessing is enabled. For example, the line "asm volatile ("B _vectors");" gets the error
"undefined reference to `_vectors'" when preprocessing is enabled, but compiles successfully whe
n I rename boot.S back to boot.s
What am I missing here?
How could we possibly tell without seeing the code in question? Post the header and the assembler
file, and the log text from the build.

You can invoke the C preprocessor standalone via cpp. That way you will be able to pre-process
the file without assembling and see the actual text that is being passed to the assembler assembled.
That will probably shed some light onto the problem.
Apologies. I turned on the -E option for GCC to check preprocessor output.
If the boot assembly file is called startarm.s, GCC goes through all the .c files and creates .o files
containing just the preprocessor output.
For startarm.s it calls arm-elf-as and creates startarm.o output without any preprocessing as expect
ed.
However, when the boot assembly file is named startarm.S, GCC does not process it at all. There
is no startarm.o produced.
So there's my problem. I have not yet figured out the correct switch(es) to make GCC assemble
a .S file.
Problem solved. Of course I should have mentioned that I'm using Eclipse/CDT for the build.
Eclipse associates *.s files as assembly files, but has no association for *.S files.
The fix is to associate *.S with "C Source File" in the File Types Preferences. Then it will pass it
to GCC.
I am pretty sure I would not have spotted the problem even had you done so. I would have created
a custom rule to run arm-elf-cpp and then arm-elf-as in sequence rather than rely on the gcc
compiler driver.

1) AIX 32 64
64 AIX 5.3 32
2) CC++COBOLFortran

C Pro*C 20K 7 15
3) Big Endian Little EndianPowerPC CPU
Big Endian x86 CPU Little Endian

4) ClientClient/ServerBrowser/Server
C/S VB Windows C Pro*C

AIX
5) XLCGCC
XLC-V11.1
6)
: -bloadmap-g-qfullpath
7) Tuxedo
SDKlibunionIBM MQ
8) OracleDB2
Oracle 10g v10.2.0.4
9) UKey

10)

11) Active DirectoryNTLM Kerberos

12) Domino

13)

AIX Linux UNIX POSIX C/C++


UNIX AIX C/C++ Linux

1 C
Proc*C 32/64
2


IBM AIX X86
AIX 5.3 64 V1564
XLC-V11.1 GCC 4.9.2
Oracle 10g (Pro*C) Oracle 10g (Pro*C)
Shell Bash Bash
IBM mqlib 32 IBM mqlib (64 )
libunion32 libunion64


1
ISO V15-20160509

2
HTTP apt-get
wget
root .bashrc
IP
export http_proxy=http://proxyusr:password@yourproxyaddress:proxyport
.bashrc .bashrc
apt-get update install

Oracle10g Oracle10gR2
V15 Oracle 10g
1.
V15 Oracle10g
32
2. Oracle 10g
Oracle
~/.bashrc
export ORACLE_BASE=/u01/app/oracle
export ORACLE_HOME=$ORACLE_BASE/product/10.2.0/dbhome_1
export PATH=$PATH:$ORACLE_HOME/bin
export ORACLE_SID=orcl
export LD_LIBRARY_PATH=$ORACLE_HOME/lib
Oracle 10g i386 architecture of input file
`.../db_1/sysman/lib/snmccolm.o' is incompatible with i386:x86-64 output Oracle
10.2.0.1 i386 x86_64
Patch10.2.0.4 relink nmccollector

2Makefile
1
Makefile
-g gdb
-bloadmap
-bnoquiet
Linux GCC Makefile
-g --verbose
2
Makefile -ldb
-lcommon -lclntsh -lenc -lmqic
3

-lsoname

gcc -m32 -g -o imgview imgview.o senddata.o -I. -L/home/user/test/lib -lpthread /home/user


/test/libabc.a
3

Oracle10g GBK
GBK UTF-8
4
Linux gdb valgrid

valgrid --tool=memcheck --leak-check=yes fileload

C
AIX C

Вам также может понравиться