2012-06-11 8 views
2

GNU의 다음과 같은 동작을 이해하고 싶습니다.GNU가 jmp에 대한 이상한 언어로 글로벌 레이블

(2.22로서 GNU) 리눅스로 인코딩 GNU하면서 OS X에 다음 테스트 프로그램 (1.38 애플 cctools-822/GNU)

.globl foo 
    jmp foo 
foo: 
    ret 

00000000 e900000000 jmp   0x00000005 
foo: 
    00000005 c3   ret 

로 부호화

       .global foo 
    0000  E9FCFFFF  jmp 0x35 # foo 
       FF 
foo: 
    0005  C3    ret 

왜 후자는 이상한 점프를합니까?

또한, 분명히이 마법 0xfcffffff 주소는 글로벌 라벨에 대한 모든 점프에 사용되는 : (2.22 같은 GNU)

test2.s

.globl foo 
    jmp foo 
    .globl bar 
    jmp bar 
    .globl baz 
    jmp baz 
foo: 
    push $1 
    ret 
bar: 
    push $2 
    ret 
baz: 
    push $3 
    ret 

리눅스에로 GNU와 생산

     .globl foo 
    0000 E9FCFFFF jmp foo 
      FF 
         .globl bar 
    0005 E9FCFFFF jmp bar 
      FF 
         .globl baz 
    000a E9FCFFFF jmp baz 
      FF 
foo: 
    000f 6A01  push $1 
    0011 C3   ret 
bar: 
    0012 6A02  push $2 
    0014 C3   ret 
baz: 
    0015 6A03  push $3 
    0017 C3   ret 

누구나 이런 종류의 행동을 설명 할 수 있습니까?

답변

2

이것은 다른 유형의 재배치 항목 (R_386_PC32)입니다.

걱정할 필요가 없습니다. 링커에서 올바른 주소를 삽입합니다.

objdump에 대해 -r 옵션을 추가하면 재배치 항목을 볼 수 있습니다 (예 : objdump).

objdump -Dr test2.o 

x86은 리틀 엔디안이므로 값은 0xfffffffc = -4입니다.

this question도 참조하십시오.

+0

고마워요, 그게 사실입니다. 어떤 종류의 문서가 있습니까? – Tobias

+0

[System V ABI, Intel386 Architecture Processor Supplement] 참조 (http://www.sco.com/developers/devspecs/abi386-4.pdf) – starblue

+0

좋습니다. 고맙습니다. – Tobias

1

실행 파일이 아닌 오브젝트를 디스 어셈블한다고 가정합니까? 이것은 모든 툴체인, 즉 선호하기 전에 객체화하기 위해 컴파일 된 모든 언어에 대해 매우 일반적입니다. 링커는 ... 객체를 연결하고, 전역 변수, 함수 이름, 변수 등을 링크합니다. 링크 단계까지는 변수 이름과 함께 주소 공간을 알 수 없기 때문에 지역에 따라 인스트럭션 세트 및 도달 범위뿐만 아니라 전역 변수는 링크 시간까지 해결 될 수 없으므로 오브젝트는 아마도 이상한 방법으로 분해 될 명령어 대신 배치 된 일종의 필러 데이터를 갖게됩니다.

+0

그러면 Apple 어셈블러가 사전에 올바른 장소를 알 수 있습니까? linux/gnu는 그렇지 않습니다. – Tobias

+0

어셈블러는 예전처럼 대상 주소를 보내야했습니다. (.org 0x1234) 또는 다른 형식을 사용하여 개체에 어셈블 링 한 다음 실행 파일에 연결하면 링커에게 배치 방법을 지정할 수 있습니다. 각 툴체인은 고유 한 솔루션을 가질 수 있습니다. 일반적으로 두 단계 (실행 개체와 연결된 개체, 개체)는 전역 지식을 가질 수 없으며 멀리 또는 멀리있는 액세스를 사용할 수 있는지 파악하기 위해 자리 표시자를 내장하여 링커에서 해결할 수 있습니다 . 정의상 그것은 링커가하는 것입니다. –

+0

gcc myprog.c -o myprog * IS *와 같은 일을하는 것은 다음과 같이 객체를 컴파일하기 위해 컴파일 한 두 단계를 수행하고 ld를 연결하도록 호출 한 다음 중간 파일을 정리하여 세 개 또는 네 개의 프로그램이 .c를 실행 파일로 만드십시오. –