Ассемблерный код

Polyspace® распознает большинство встроенных ассемблеров введением ассемблерного кода. Верификация игнорирует ассемблерный код, но составляет то, что ассемблерный код может изменить переменные в коде С.

Если введение ассемблерного кода вызывает ошибки компиляции:

  1. Встройте ассемблерный код между #pragma my_asm_begin и оператором #pragma my_asm_end.

  2. Задайте аналитическую опцию -asm-begin my_asm_begin -asm-end my_asm_end.

Для получения дополнительной информации смотрите -asm-begin -asm-end.

Распознанные встроенные ассемблеры

Polyspace распознает эти встроенные ассемблеры введением ассемблерного кода.

  • asm

    Примеры:

    • 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__

    Примеры:

    • 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 endasm

    Примеры:

    • 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++;
      }

Одна функция, содержащая ассемблерный код

Программное обеспечение блокирует функцию, которой предшествует asm, даже если тело задано.

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 
}

Несколько функций, содержащих ассемблерный код

Функции, которые вы задаете через следующую прагму, заблокированы автоматически, даже если тела функции заданы.

#pragma inline_asm(list of functions)

Примеры кода:

#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 
}

Локальные переменные в функциях с ассемблерным кодом

Верификация игнорирует содержимое инструкций по ассемблеру, но следование инструкциям, это делает некоторые предположения о:

  • Неинициализированные локальные переменные: инструкции по блоку могут инициализировать эти переменные.

  • Инициализированные локальные переменные: инструкции по блоку могут записать любое возможное значение в переменные, позволенные типами данных переменных.

Например, функциональному f ввели ассемблерный код через оператор asm.

int f(void) { 
    int val1, val2 = 0; 
    asm("mov 4%0,%%eax"::"m"(val1));
    return (val1 + val2); 
}
На операторе return проверка Non-initialized local variable имеет следующие результаты:

  • val1: проверка является оранжевой, потому что инструкция по блоку может инициализировать val1.

  • val2: проверка является зеленой. Однако val2 может иметь любое значение int.

Если переменная статична, предположения верны где угодно в теле функции, даже перед инструкциями по блоку.