저는 여전히 g ++ 인라인 어셈블러에 어려움을 겪고 있으며 사용법을 이해하려고합니다.g ++에서 간단한 디스 어셈블 된 코드를 이해하려고 시도했습니다.
는 여기에서 코드 조각을 채택했습니다 http://asm.sourceforge.net/articles/linasm.html은 (GCC 정보 파일의 섹션 "C 표현식 피연산자와 어셈블러 지침"에서 인용) 내가 사용하지 최적화를 컴파일 한
static inline uint32_t sum0() {
uint32_t foo = 1, bar=2;
uint32_t ret;
__asm__ __volatile__ (
"add %%ebx,%%eax"
: "=eax"(ret) // ouput
: "eax"(foo), "ebx"(bar) // input
: "eax" // modify
);
return ret;
}
:
g++ -Og -O0 inline1.cpp -o test
디스 어셈블 된 코드 나 퍼즐 :
(gdb) disassemble sum0
Dump of assembler code for function sum0():
0x00000000000009de <+0>: push %rbp ;prologue...
0x00000000000009df <+1>: mov %rsp,%rbp ;prologue...
0x00000000000009e2 <+4>: movl $0x1,-0xc(%rbp) ;initialize foo
0x00000000000009e9 <+11>: movl $0x2,-0x8(%rbp) ;initialize bar
0x00000000000009f0 <+18>: mov -0xc(%rbp),%edx ;
0x00000000000009f3 <+21>: mov -0x8(%rbp),%ecx ;
0x00000000000009f6 <+24>: mov %edx,-0x14(%rbp) ; This is unexpected
0x00000000000009f9 <+27>: movd -0x14(%rbp),%xmm1 ; why moving variables
0x00000000000009fe <+32>: mov %ecx,-0x14(%rbp) ; to extended registers?
0x0000000000000a01 <+35>: movd -0x14(%rbp),%xmm2 ;
0x0000000000000a06 <+40>: add %ebx,%eax ; add (as expected)
0x0000000000000a08 <+42>: movd %xmm0,%edx ; copying the wrong result to ret
0x0000000000000a0c <+46>: mov %edx,-0x4(%rbp) ; " " " " " "
0x0000000000000a0f <+49>: mov -0x4(%rbp),%eax ; " " " " " "
0x0000000000000a12 <+52>: pop %rbp ;
0x0000000000000a13 <+53>: retq
End of assembler dump.
예상대로 sum0() 함수는 잘못된 값을 반환합니다.
의견이 있으십니까? 무슨 일 이니? 그것을 올바르게 얻는 방법?
- 편집 - 은 @MarcGlisse의 의견을 바탕으로, 나는 시도 :
static inline uint32_t sum0() {
uint32_t foo = 1, bar=2;
uint32_t ret;
__asm__ __volatile__ (
"add %%ebx,%%eax"
: "=a"(ret) // ouput
: "a"(foo), "b"(bar) // input
: "eax" // modify
);
return ret;
}
내가 다음 봤는데 튜토리얼이 잘못된 것 같습니다. 출력/입력 필드의 "eax"는 레지스터 자체를 의미하지는 않지만 abbrev 테이블의 e, a, x 약어를 의미합니다.
어쨌든, 나는 여전히 올바르게하지 않습니다. 위의 코드는 컴파일 오류를 발생시킵니다. 'asm'피연산자에는 불가능한 제약 조건이 있습니다.
이유가 표시되지 않습니다.
최적화를 사용하면 더 쉽게 이해할 수 있습니다. –
"eax"는 자신이 생각하는 것을 의미하지 않으며 "a"를 원합니다. 그리고 출력물이 구석 구석을 표시 할 필요가 없습니다. –
좀 더 자세히 읽으십시오 : "출력이 마비 된 것으로 표시 할 필요가 없습니다". –