2010-07-19 3 views
2

빈 메모리 요소를 레지스터에로드하는 명령어를 생성하는 것이 컴파일러 (예 : gcc)에서 일반적입니까? 마찬가지로 ... lw, 0 (sp) 여기서 memory [sp + 0] = 0. 기본적으로 0은 $ at ($ R1.)에 저장됩니다. 실행 파일의 16 진 덤프 (실행 파일 C++ 파일을 컴파일 한 결과입니다.) 수동으로 확인 중이며 objdump 상태 진입 점에서 시작하면이 작업을 수행하는 명령이 실행됩니다. 나는 그것이 일반적인 컴파일러 동작이라면 이것이 에러가되도록해야하는지 확신 할 수 없다. 그것은 레지스터를 0으로 만드는 나쁜 방법처럼 보입니다. ADDU $ at, $ 0, $ 0은 더 좋을 것입니다. 또는 SLL $ at, $ 0, $ 0 ..간단한 MIPS 명령어와 컴파일러

엔트리 포인트는 400890입니다. 끝에있는 jal의 점프 대상은 빈 메모리 위치입니다 (뭔가 잘못된 것 같습니다 ...). 이전 예제 의도적으로 중재되었습니다.

그리고 분명히 -32636 + gp는 빈 메모리 위치입니다. 나는 당신이 증거를 원한다면 그 시점에서 기억 내용을 게시 할 수있다. :).

00400890 <__start>: 
    400890: 03e00021 move zero,ra 
    400894: 04110001 bal 40089c <__start+0xc> 
    400898: 00000000 nop 
    40089c: 3c1c0fc0 lui gp,0xfc0 
    4008a0: 279c7864 addiu gp,gp,30820 
    4008a4: 039fe021 addu gp,gp,ra 
    4008a8: 0000f821 move ra,zero 
    4008ac: 8f848034 lw a0,-32716(gp) 
    4008b0: 8fa50000 lw a1,0(sp) 
    4008b4: 27a60004 addiu a2,sp,4 
    4008b8: 2401fff8 li at,-8 
    4008bc: 03a1e824 and sp,sp,at 
    4008c0: 27bdffe0 addiu sp,sp,-32 
    4008c4: 8f878054 lw a3,-32684(gp) 
    4008c8: 8f888084 lw t0,-32636(gp)<------ this instruction 
    4008cc: 00000000 nop 
    4008d0: afa80010 sw t0,16(sp) 
    4008d4: afa20014 sw v0,20(sp) 
    4008d8: afbd0018 sw sp,24(sp) 
    4008dc: 8f998068 lw t9,-32664(gp) 
    4008e0: 00000000 nop 
    4008e4: 0320f809 jalr t9 
    4008e8: 00000000 nop 

Jal 목표는 4010c0입니다.

4010c0: 8f998010 lw t9,-32752(gp) 
    4010c4: 03e07821 move t7,ra 
    4010c8: 0320f809 jalr t9 
+0

필자는 MIPS에 익숙하지 않지만 스택에서 값을로드하고 있습니다. 아마도 함수 인수 일 수 있습니다. 프로그램 입력 지점 인 경우 명령 줄 인수를 제공하기 위해 런타임에서 제공 될 수도 있습니다. 이 값은 런타임까지 알 수 없기 때문에 컴파일러는 이것이 0이라고 가정 할 수 없습니다. –

+0

저는 런타임 동안이 명령에 대해 실제로 말하고 있습니다. 의미 이것은 프로그램 엔트리 포인트 다음에 10이나 어떤 것을 지시 할 것이고로드되기 전의 메모리 요소를 할당하기 전에이 명령이 없다. 이것은 고의적 인 (적절하게 적용되지 않은) nop이거나 실행 파일의 한 부분이 .text 섹션 앞에로드되어야한다고 알려줍니다. –

+0

컨텍스트를 추가 할 수 있습니까? 아마도 5 ~ 10 개의 지침을 전후에 붙여 넣을 수 있습니까? – bstpierre

답변

0

아마도 점프 선언문 뒤에 위치 할 것입니까? 그렇다면 점프가 발생하기 전에 해당 명령문이 실행되고 do nothing 명령 (nop)이 될 수 있습니다. 그보다 낮은 최적화 설정에서는 컴파일러가 될 수 있습니다. 또 다른 가능성은 컴파일러가 CPU 플래그 필드를 보존한다는 것입니다. 내가 믿지 않는로드가있는 동안 Shift와 Add 플래그를 사용하여 플레이하십시오.

+0

실제로 ADDU 다음에 LW 뒤에 놓인다. 로드 지연이 비활성화 되었기 때문에 대상 레지스터에 실제로 0이 아닌 값이 할당되어 있다고 확신합니다. 그러나 이것은 readelf 및 objdump에 의해 정의 된 진입 점이 실제로 실행되어야하는 첫 번째 명령이 아님을 의미합니다. –

+0

그러면 코드에 ADDU 호출의 플래그가 필요합니까? 그렇다면 할당이 설명 될 수 있습니다. 또한, 어떤 최적화 수준을 사용하고 있습니까? –

+0

03 내가 사용하는 최적화입니다. 또한, 점프/분기 지연 슬롯은 마지막 명령으로 볼 수있는 것처럼 아무것도 넣을 수 없을 때 nop으로 채워집니다. –

0

이것은 CRT 코드와 유사합니다. 나는이 코드가 $ a0과 $ a1 레지스터에 OS에 의해 전달 된 매개 변수를로드하고 있다고 생각한다. 아마도 더 큰 구조체가 스택에 전달되고 코드가 해당 구조체를로드하여 스택 위치를 수정합니다. 이 코드는 C 컴파일러에서 생성하지는 않지만 어셈블리에서 직접 코딩 한 것입니다.