Code Prover Assumptions About Assembly Code
Polyspace® recognizes most inline assemblers as introduction of assembly code. The analysis ignores the assembly code but accounts for the fact that the assembly code can modify variables in the C code.
Recognized Inline Assemblers
Polyspace recognizes these inline assemblers as introduction of assembly code.
asmExamples:
int f(void) { asm ("% reg val; mtmsr val;"); asm("\tmove.w #$2700,sr"); asm("\ttrap #7"); asm(" stw r11,0(r3) "); assert (1); // is green return 1; }int other_ignored2(void) { asm "% reg val; mtmsr val;"; asm mtmsr val; assert (1); // is green asm ("px = pm(0,%2); \ %0 = px1; \ %1 = px2;" : "=d" (data_16), "=d" (data_32) : "y" ((UI_32 pm *)ram_address): "px"); assert (1); // is green }int other_ignored4(void) { asm { port_in: /* byte = port_in(port); */ mov EAX, 0 mov EDX, 4[ESP] in AL, DX ret port_out: /* port_out(byte,port); */ mov EDX, 8[ESP] mov EAX, 4[ESP] out DX, AL ret } assert (1); // is green }
__asm__Examples:
int other_ignored6(void) { #define A_MACRO(bus_controller_mode) \ __asm__ volatile("nop"); \ __asm__ volatile("nop"); \ __asm__ volatile("nop"); \ __asm__ volatile("nop"); \ __asm__ volatile("nop"); \ __asm__ volatile("nop") assert (1); // is green A_MACRO(x); assert (1); // is green return 1; }int other_ignored1(void) { __asm {MOV R8,R8 MOV R8,R8 MOV R8,R8 MOV R8,R8 MOV R8,R8} assert (1); // is green }int GNUC_include (void) { extern int __P (char *__pattern, int __flags, int (*__errfunc) (char *, int), unsigned *__pglob) __asm__ ("glob64"); __asm__ ("rorw $8, %w0" \ : "=r" (__v) \ : "0" ((guint16) (val))); __asm__ ("st g14,%0" : "=m" (*(AP))); __asm("" \ : "=r" (__t.c) \ : "0" ((((union { int i, j; } *) (AP))++)->i)); assert (1); // is green return (int) 3 __asm__("% reg val"); }int other_ignored3(void) { __asm {ldab 0xffff,0;trapdis;}; __asm {ldab 0xffff,1;trapdis;}; assert (1); // is green __asm__ ("% reg val"); __asm__ ("mtmsr val"); assert (1); // is green return 2; }
#pragma asm #pragma endasmExamples:
int pragma_ignored(void) { #pragma asm SRST #pragma endasm assert (1); // is green }void test(void) { #asm mov _as:pe, reg jre _nop #endasm int r; r=0; r++; }
Bypassing Unrecognized Assembly Instructions
If introduction of assembly code causes compilation errors:
Embed the assembly code between a
#pragmaand amy_asm_begin#pragmastatement.my_asm_endSpecify the analysis option
-asm-begin.my_asm_begin-asm-endmy_asm_end
For more information, see -asm-begin -asm-end.
Analysis Assumptions Around Assembly Instructions
Entire Functions Containing Assembly Code
Single Function. The software stubs a function that is preceded by asm, even if a body is defined.
asm int h(int tt) // function h is stubbed even if body is defined
{
% reg val; // ignored
mtmsr val; // ignored
return 3; // ignored
};
void f(void) {
int x;
x = h(3); // x is full-range
}
Groups of Functions. The functions that you specify through the following pragma are stubbed automatically, even if function bodies are defined.
#pragma inline_asm(list of functions)
Code examples:
#pragma inline_asm(ex1, ex2)
// The functions ex1 and ex2 are
// stubbed, even if their bodies are defined
int ex1(void)
{
% reg val;
mtmsr val;
return 3; // ignored
};
int ex2(void)
{
% reg val;
mtmsr val;
assert (1); // ignored
return 3;
};
#pragma inline_asm(ex3) // the definition of ex3 is ignored
int ex3(void)
{
% reg val;
mtmsr val; // ignored
return 3;
};
void f(void) {
int x;
x = ex1(); // ex1 is stubbed : x is full-range
x = ex2(); // ex2 is stubbed : x is full-range
x = ex3(); // ex3 is stubbed : x is full-range
}
Functions Containing Mix of C/C++ and Assembly Code
The analysis ignores the content of assembly language instructions, but following the instructions, it makes some assumptions about:
Uninitialized local variables: The assembly instructions can initialize these variables.
Initialized local variables: The assembly instructions can write any possible value to the variables allowed by the variable data types.
If you use a GCC compiler and specify the input and output
variables of the asm block, Polyspace recognizes which variable are read or written to in the assembly
code. This information improves the precision of the analysis when you use GCC
compilers.
For instance, the function f has assembly code introduced
through the asm
statement.
int f(void) {
int val1, val2 = 0;
asm("mov %0,%%eax"::"m"(val1));
return (val1 + val2);
}return statement, the
Non-initialized local variable check has the following results:
GCC or clang compilers — If you use a GCC or clang compiler, Polyspace recognizes that the assembly code reads the variable
val1and does not write into any of the local variable. Polyspace can determine that thevariableva1is not initialized in any code path before use and reports red Non-initialized local variable onval1.Other compilers — If you use compilers other than GCC or clang, Polyspace assumes that the
asmblock can modify any variable in the local scope. Polyspace assumes that the variableval1can be initialized in theasmblock and reports orange Non-initialized local variable onval1.
If the variable is static, the assumptions are true anywhere in the function
body, even before the assembly instructions. If you want to avoid these
conservative assumptions and ignore the assembly instructions altogether,
specify the analysis option Ignore
assembly code (-ignore-assembly-code).
See Also
-asm-begin -asm-end | Ignore assembly code (-ignore-assembly-code)