변환 후 코드가 지정된 작업을 실행하지 않음 [중복]
Dec 18 2020
AT & T 구문을 기반으로 특정 코드를 C ++에서 ASM으로 변환하는 작업이 주어 졌기 때문에 간단한 예제로 시작하여 첫 번째 문제가 발생했습니다.
연습을 시작한 코드
void func() {
int num = 1;
std::cout << "before: " << num << std::endl;
num = num << 3;
std::cout << "after: " << num << std::endl;
}
결과를 제공합니다.
before: 1
after: 8
내 번역 변수 num은 첫 번째 지역 변수이므로 주소 -4 (% ebp)에 있어야합니다.
void func() {
int num = 1;
std::cout << "before: " << num << std::endl;
asm (
"mov -4(%ebp), %eax \n"
"sall $3, %eax \n"
"mov %eax, -4(%ebp) \n"
);
std::cout << "after: " << num << std::endl;
}
결과를 제공합니다.
before: 1
after: 1
이 코드가 num var에 영향을 미치지 않는 이유는 무엇입니까?
답변
2 JHBonarius Dec 18 2020 at 02:17
작성중인 코드는 구현에 따라 매우 다릅니다. 귀하의 경우에는 ebp
32 비트 주소 지정 레지스터를 사용하고 .NET을 사용하는 64 비트 컴퓨터에서 실행 중이기 때문에 코드가 작동하지 않을 수 있습니다 rbp
.
그러나 당신은 이것에 잘못 접근하고 있습니다. 순수 어셈블리를 작성하거나 로컬 변수와 올바르게 인터페이스하는 올바른 (확장) C 인라인 어셈블리를 사용합니다. 그렇지 않으면 경험 한 것처럼 무언가를 변경하자마자 코드가 깨질 것입니다.
이 답변에 따르면 인라인 asm은 다음과 같아야합니다.
asm ( "assembly code"
: output operands /* optional */
: input operands /* optional */
: list of clobbered registers /* optional */
);
그래서 당신의 코드는
asm (
"mov %0, %%eax;"
"sal $3, %%eax;"
"mov %%eax, %1;"
:"=r" (num)
:"r" (num)
:"%eax"
);
그러나을 지정하고 사용할 필요가 없으므로 eax
코드를 다음과 같이 단순화 (및 명확화) 할 수 있습니다.
asm (
"sal $3, %[num];"
:[num] "+r" (num)
);