I am trying to generate a undefined instruction by using pseudo-instruction mentioned in http://www.keil.com/support/man/docs/armasm/armasm_dom1361289918908.htm
My inline assembly code like below:
__asm volatile ("UND 0xe7f000f0")
However I got this error:
Error: #3061: unrecognized instruction opcode
To me seems like UND is not recognized as no matter how I play with the 0xe7f000f0 value part , always show this error, would like to know if anyone tried the UND instruction and what might be wrong in my inline assembly?
Related
I'm programming STM8 micro controller in STVD. I happen to use an assembly instruction in the middle of code. As shown here
I used a instruction as below
asm("MOV $00500A,#$3");
But I'm facing with following error
#error cpstm8 ..\app\sched.c:183(5) missing prototype
Can anyone help me in fixing this?
For STM8 assembly instruction, you need to use _ before the instruction as shown below
_asm("MOV $00500A,#$3");
I want to compile a program with gcc with link time optimization for an ARM processor. When I compile without LTO, the system gets compiled. When I enable LTO
(with -flto), I get the following assembler-error:
Error: invalid literal constant: pool needs to be closer
Looking around the web I found out that this has something to do with the constants in my system, which are placed in a special section called .rodata, which is called a constant pool and is placed right after the .text section in my system. It seems that when compiling with LTO because of inlining and other optimizations this .rodata section gets too far away from the instructions, so that the addressing of the constants is not possible anymore. Is it possible to place the constants right after the function that uses them? Or is it possible to use another addressing mode so the .rodata section can still be addressed? Thanks.
This is an assembler message, not a linker message, so this happens before sections are generated.
The assembler has a pseudo instruction for loading constants into registers:
ldr r0, =0x12345678
this is expanded into
ldr r0, [constant_12345678, r15]
...
bx lr
constant_12345678:
dw 0x12345678
The constant pool usually follows the return instruction. With function inlining, the function can get long enough that the return instruction is too far away; unfortunately, the compiler has no idea of the distance between memory addresses, and the assembler has no idea of control flow other than "flow does not pass beyond the return instruction, so it is safe to emit the constant pool here".
Unfortunately, there is no good solution at the moment.
You could try an asm block containing
b 1f
.ltorg
1:
This will force-emit the constant pool at this point, at the cost of an extra branch instruction.
It may be possible to instruct the assembler to omit the branch if the constant pool is empty, but I cannot test that at the moment, so this is probably not valid:
.if (2f - 1f)
.b 2f
.endif
1:
.ltorg
2:
"This is an assembler message, not a linker message, so this happens before sections are generated" - I am not sure but I think it is a little bit more complicated with LTO. Compiling (including assembling) of the individual c-files with LTO enabled works fine and does not cause any problems. The problem occurs when I try to link them together with LTO enabled. I don't know how LTO is exactly done, but apparently this also includes calling the assembler again and then I get this error message. When linking without LTO, everything is fine and when I look at the disassemly I can see that my constants are not placed after a function. Instead all constants are placed in the .rodata section. With LTO enabled because of inlining, my functions probably get to large to reach the constant pool...
I have a small question about using ASM in c. I want to execute the instruction:
LDR PC,=0x123456
This gives me the error "unexpected token in operand".
asm("LDR PC,=0x123456");
This gives "invalid constraint".
asm("LDR PC," : "m" (0x123456));
What's the right way to do this?
You are using this:
asm("LDR PC,=0x123456");
This is not a standard ARM assembly instruction, but a pseudo-instruction provided as a compiler extension. This pseudo-instruction is converted to other assembly instructions when you compile it. It seems clang doesn't support this compiler extension (see this thread). You should do the conversion to assembly instructions yourself, see the ARM documentation for how the LDR pseudo-instruction is converted.
You can probably achieve the effect you want in plain C:
((void (*)(void))0x123456)();
or if you prefer more verbose:
typedef void FN(void);
((FN*)0x123456)();
I agree with #Étienne. I tried you code with mi Google toolchain. It's working fine.
I think you should read the manual how the compiler changes the directive to instructions (normally two mov instructions).
When I compile my code I am getting a unknown Opcode '.pword' error. The only line of code in my project that has .pword is:
do {
__asm__ volatile (" .pword 0xDA4000");
Nop();
} while(0)
Commenting the line out does nothing.
I searched .pword 0xDA4000 and know it is supported by the IDE MPLab for PICs.
In my case the IDE I am using is CrossStudio for a STMf32f2xx chip.
I have the updated CrossStudio which comes with binutils 2.21 and gcc 4.6.0
I initially had a problem with compiling unnamed structs and unions but adding -fms-extensions into additional C compiler options fixed it.
I dont know if I need to do something similar to fix Opcode '.pword' error.
could it just be that .pword is only a PIC opcode?
In MPLAB ASM30 assembler the .pword declare 24 bit constant in code memory. It can be also any MPLAB ASM30 instruction.
Check: MPLAB ASM30 assembler
Silly question, but I just can not find the necessary flag in gcc. Basically, I have in my C program the following inline assembler code
__asm__ __volatile__ ("lea ebx, [timings] \n\t");
When compiling, I get an errormessage which says: Error: invalid char '[' beginning operand 2[timings]'`
Now I remember that a long time ago I used some kind of flag that told the compiler that it is x86 inline assembly. But cant find it online, could maybe someone please tell me which flag i have to use?
Thank you so much!
You can't specify variables that way with GCC. See this document for a detailed description of how to use inline assembler. Also, keep in mind that GCC uses AT&T syntax, not Intel syntax, so you have to put your destinations on the right.
Try using __asm__ instead. Look here for more.
Also, try removing the \n\t from inside the assembly code.