C Macro - 정수 값을 문자열 리터럴로 가져오는 방법
GCC(AVR Studio)의 어셈블리 섹션의 일부인 문자열 리터럴에 #정의 정수 기호를 삽입할 값을 얻을 수 있습니까?
아래 asm() 블록 안에 있는 문자열 리터럴 안에 있는 "LED"를 48개로 교체했으면 합니다.
#define LEDS 48 //I only want ONE mention of this number in the source
int x = LEDS; //I'm using the value directly too
void DrawFrame()
{
asm(
"ldi R27, 0x00 \n\t"
"ldi R26, 0x00 \n\t"
"ldi R18, LEDS \n\t" //<-- substitution needed here
...
}
하지만 컴파일러/어셈블러(사전 프로세서가 작업을 완료한 후)가 이것을 볼 수 있기를 바랍니다.
#define LEDS 48 //I only want ONE mention of this number in the source
int x = LEDS; //I'm using the value directly too
void DrawFrame()
{
asm(
"ldi R27, 0x00 \n\t"
"ldi R26, 0x00 \n\t"
"ldi R18, 48 \n\t" //<-- substitution needed here
...
}
지금까지 제가 생각할 수 있는 모든 매크로 트릭(#스트링, arg 치환, 심지어 #값과 큰따옴표의 다양한 조합을 가진 파일 포함)을 시도했습니다.
저는 AVR 스튜디오의 GCC 컴파일러에 AVR 어셈블리 코드를 입력하는 마법에 전혀 익숙하지 않습니다.
저는 제 소스에 "48" 리터럴이 여러 번 발생하는 것을 피하려고 합니다. 만약 전처리기가 저를 대신해서 이런 대체 작업을 수행할 수 있다면 좋을 것입니다.
편집: 마이크로컨트롤러 펌웨어 프로젝트를 위한 것입니다. 삶을 재미있게 만들기 위해 새로운 코드를 추가할 여유 공간이 거의 없습니다.
Utils 헤더에 문자열화 매크로가 있는 것이 좋다고 생각합니다.
#define STR_IMPL_(x) #x //stringify argument
#define STR(x) STR_IMPL_(x) //indirection to expand argument macros
그런 다음 매크로를 숫자로 유지하고 그 자리에서 문자열화할 수 있습니다.
#define LEDS 48
int x = LEDS;
void DrawFrame()
{
asm(
"ldi R27, 0x00 \n\t"
"ldi R26, 0x00 \n\t"
"ldi R18, "STR(LEDS)" \n\t"
...
}
위의 전처리 과정은 다음과 같습니다.
int x = 48;
void DrawFrame()
{
asm(
"ldi R27, 0x00 \n\t"
"ldi R26, 0x00 \n\t"
"ldi R18, ""48"" \n\t"
...
}
인접한 문자열 리터럴이 연결된다는 사실에 의존합니다.
다른 방법으로, 당신은 다음과 같이 만들 수 있습니다.STR
쉼표에 관대한 매크로:
#define STR_IMPL_(...) #__VA_ARGS__ //stringify argument
#define STR(...) STR_IMPL_(__VA_ARGS__) //indirection to expand argument macros
그리고 전체를 끈으로 묶는 겁니다asm
다음과 같은 차체:
asm( STR(
ldi R27, 0x00;
ldi R26, 0x00;
ldi R18, LEDS; //LEDS gets expanded
)); //renders: "ldi R27, 0x00; ldi R26, 0x00; ldi R18, 48;"
(개인적으로 명시적인 문자열 리터럴보다 편리하다고 생각하여 clang/gcc/tinycc에 이렇게 글을 씁니다.)이 접근 방식은 조립품이 단지 하나의 라인일 뿐이며 조립자가 또한 수용하는 한 조립될 것이라는 잠재적인 단점을 가지고 있습니다.;
새로운 라인과 더불어 명령어 구분자로서(적어도 clang/gcc/ tinycc의 x86-64 어셈블리에 대해 작동).
제약 조건을 사용하는 경우 문자열화 매크로가 발생하지 않도록 할 수 있습니다.
#define LEDS 48
void DrawFrame()
{
asm volatile(
"ldi R18, %[leds]"
: : [leds] "M" (LEDS) : "r18");
}
이것이 작동하려면 보조 매크로가 두 개 필요합니다.그러면 자동 문자열 연결을 이용할 수 있습니다.
#define STR(x) #x
#define EXPAND(x) STR(x)
#define LEDS 48
int x = LEDS;
void DrawFrame()
{
asm(
"ldi R27, 0x00 \n\t"
"ldi R26, 0x00 \n\t"
"ldi R18, " EXPAND(LEDS) " \n\t"
...
}
매크로를 두 개 사용하는 이유는 첫 번째 것만으로는 전달된 파라미터가 확장되지 않기 때문입니다.
만약 당신이 이렇게 했다면:
printf("LEDS = " STR(LEDS) "\n");
다음과 같이 확장됩니다.
printf("LEDS = " "LEDS" "\n");
그EXPAND
macro를 사용하면 전달된 매개 변수도 대체할 수 있습니다.
그럼 다음은.
printf("LEDS = " EXPAND(LEDS) "\n");
다음으로 확장:
printf("LEDS = " "48" "\n");
언급URL : https://stackoverflow.com/questions/40591312/c-macro-how-to-get-an-integer-value-into-a-string-literal
'programing' 카테고리의 다른 글
로그인 재연결 후 wocommerce (0) | 2023.11.04 |
---|---|
기본 게시물의 영구 링크를 변경하는 방법? (0) | 2023.11.04 |
MySQL에서 JOIN 쿼리의 반환 결과를 제한하는 방법 (0) | 2023.11.04 |
Oracle LOB를 삭제하는 방법 (0) | 2023.11.04 |
오류 ORA-01804 텍스트를 검색하는 중 오류 발생 (0) | 2023.10.30 |