본문 바로가기
개발도구

Visual Studio ] NO Operation 코드

by eteo 2024. 12. 9.

 

 

보통 GCC에선 코드의 특정 위치에서 아무 작업도 하지 않고 시간을 잠시 지연시키거나 디버깅 시 브레이크포인트를 목적으로 asm("nop"); 구문을 많이 사용한다. 

 

여기서 asm은 어셈블리를 코드에 삽입할 수 있도록 해주는 GCC 확장이고 nop은 아무 작업도 수행하지 않는 어셈블리 명령어로 프로세서가 이 명령어를 만나면 한 사이클 동안 아무 작업도 하지 않고 넘어간다.

 

asm(  "nop");

 

 

 

Visual Studio에서 사용 가능한 NO Operation 코드

 

그럼 MSVC(Microsoft Visual Studio Compiler) x64 에서는 이와 유사한 방식으로 어떻게 아무 작업도 하지 않으면서 필요시 브레이크포인트를 설정할 수 있는 코드를 작성할 수 있을까?

 

먼저 __noop; 과 (void)0; 을 시도해 봤는데 아무 작업도 수행하지 않는 것은 맞았지만 컴파일러가 최적화하면서 브레이크 포인트를 찍을 수 없었다.

 

 

 

 

첫번째 방법

 

__nop(); 함수를 사용하는 방법인데 <intrin.h> 헤더파일을 포함시켜야 한다.

#include <intrin.h>

__nop();

 

참고 : https://learn.microsoft.com/ko-kr/cpp/intrinsics/nop?view=msvc-170

 

 

 

 

두번째 방법

 

다음과 같이 매크로를 만들어서 사용하는 방식이다. 

#define NOP() do { volatile int dummy = 0; (void)dummy; } while(0)

NOP();

 

volatile 키워드를 사용하면 컴파일러가 변수를 최적화하지 못하게 하여 그 부분에 브레이크포인트를 설정할 수 있게 된다. 

이 매크로는 호출될 때마다 새로운 스코프를 { } 생성하고 그 안에서 dummy 변수를 선언하므로 동일한 스코프 내에서 NOP();을 여러번 호출해도 충돌 없이 사용할 수 있다.

dummy 변수를 만들고 (void)dummy; 를 해준 것은 혹시라도 dummy 변수가 사용되지 않아서 발생하는 unused variable 경고를 억제하기 위함이고 해당 구문이 한번만 실행되는데도 굳이 do {...} while(0) 문을 사용한 이유는 if-else문과 결합하여 사용하였을 때 if의 코드 블록으로 오해되어 else문과 결합이 안되는 문제가 없게 하기 위함이다.