2010-03-05 2 views
1

누구나 내게 다음 C++ 코드의 GCC에 의해 생성 된 어셈블리를 설명 할 수 있습니까? espeically, 코드에서 setg와 test의 의미. 고마워!도움이 생성 된 어셈블리 코드의 부분을 이해하십시오

의 .cpp 코드 :

1 /*for loop*/ 

2 int main() 

3 { 
4  int floop_id; 

5  for(floop_id=100;floop_id>=1;floop_id--) 
6  {} 
7  return 0; 
8 } 

어셈블리 코드 : 그것은 g reater의 경우

3  push %ebp    
3  mov %esp, %ebp   
3  sub $0x10,%esp   
5  movl $0x64,-0x4(%ebp) 
5  jmp 8048457<main+0x13> 
5  subl $0x1,-0x4(%esp)  
5  cmpl $0x0,-0x4(%esp)  
5  setg %al     
5  test %al, %al   
7  mov $0x0,%eax   
8  leave     
8  ret 

답변

3

cmpl $0x0,-0x4(%esp); setg %al 수단이 0에 대하여 (코드에서 floop_id) -0x4(%esp) 비교하고, 1 %al를 설정, 그렇지 않으면 0입니다.

test %al, %al 여기서는 아무 것도하지 않습니다. 나는 그것이 왜 어셈블리에 있는지 알지 못합니다. (일반적으로 test 자체 값을 사용하여 값의 부호를 얻습니다 (예 : 0, 양수 또는 음수). 그러나이 결과는 여기에서 사용되지 않습니다. 가능성은 조건부 분기 (루프를 구현)하지만 루프가 비어있는 것처럼 보이면 제거됩니다.)

+0

답장을 보내 주셔서 감사합니다. 나는 하나 개의 흥미로운 점을 발견 : 나는 위와 같은 코드를 사용하여 GCC와 C 코드를 컴파일 할 때, 생성 된 어셈블리 코드가 다른 : 80483a3 이 cmpl의 $ 0x0으로, -0x4 (특히 %) JG setg 및 테스트 지침이 없습니다. 그러나 다른 것은 동일합니다. 가능한 이유를 아십니까? 고마워! – martin

+0

@martin : C 프론트 엔드는 C++ 프론트 엔드와 달리 빈 루프 본문을 "제거"하지 않기로했습니다. :-) 다른 최적화 플래그 (예 :'-O1','-O2')로 컴파일 해보십시오. 극적으로 다른 결과가 나타납니다. –

+0

다른 최적화 플래그로 시도했지만 어셈블리는 동일합니다. 미안 해요, 빈 루프 몸체를 벗겨 내면 어떨까요? 어셈블리 코드에 어떤 영향을 줍니까? 정말 고마워! – martin

0

생성 된 어셈블리 코드에는주기가 없습니다 (컴파일러에서 필요하지 않다고 판단한 것 같습니다). 그러나 그것은 그주기의 느슨한 나머지를 포함하고있는 것처럼 보입니다. 변수에 100을로드하고 1을 빼고 0과 비교하는 비트가 있습니다. 그러나 코드에는 실제 반복이 없습니다.

여기에서 어떤 논리를 찾으려는 시도는 무의미합니다. 컴파일러는 분명히 전체주기를 제거하기로 결정했습니다. 그러나 왜 "파편"이 남았는지 확실하지 않습니다. 코드에 남아있는 것은 무해한 것이지만 동시에 초기화 된 변수의 값만큼 많은 의미가 있다고 말할 수 있습니다.

현재, 무조건적으로 jmp은 어디로 이어 집니까? 분해로 인해 명확하지 않습니다. 당장 7시 바로 뛰지 않니?

관련 문제