2013-05-21 4 views
2

내 코드의 각 줄마다 주소를 확인하고 싶습니다. 내가 알고 싶은 :프로그램에서 각 변수, 포인터, 함수, 함수 반환 주소 등의 주소를 아는 방법은 무엇입니까?

  • 변수가 만들어 질 때, 어떤 주소에?
  • 함수가 만들어 질 때, 어떤 주소에?
  • 함수가 반환되면 어떤 주소에 있습니까?

여기서 무엇을하려고합니까? dumpbin을 사용하여 정보를 가져옵니다.

나는 무엇을 기대합니까?

fun main add:0x0000 
var int i add:0x2496 
var int j add:0x249A 

적절한 설명과 함께 적절한 도움을 주실 수 있습니다.

+0

코드 줄에는 편집기가 제외하고 주소가 없습니다. 하지만 에뮬레이터에서 코드를 실행하고 모든 명령을 수행 한 후에 검사 할 수 있습니다 (느려지 겠지만). –

+0

어떤 OS입니까? C에서 모든 변수가 주소를 가지고있는 것은 아니며 (레지스터에 선언 된 것들, 레지스터에 엔트리 된 것들, 존재하지 않는 것들에 최적화되어있는 것들)주의하십시오. – Jens

+1

"코드 줄에는 주소가 없습니다"- 어떤 사람들은 컴퓨터 또는 툴체인의 작동 방식에 대해 많이 알지 못하는 것 같습니다. http://en.wikipedia.org/wiki/DWARF : "코드 위치와 소스 코드 위치를 매핑하는 라인 번호 테이블"을 참조하십시오. –

답변

2

요청하신 정보는 컴파일러가 생성 한 객체 코드의 정상적인 부분이 아니며 일반적으로 객체 코드 또는 일반 심볼 테이블을 검사하여 완전히 얻을 수 없습니다. 이 정보의 대부분은 목적 코드의 목적이 단순히 프로그램을 실행하는 것이 가능하기 때문에 목적 코드에 유지되지 않습니다. 오브젝트 코드의 원점에 관한 정보 (소스 코드를 작성한 소스 행이나 소스에 사용 된 이름 등)는 실행에 간단하게 불필요합니다.

요청한 정보 중 상당수는 GCC 로의 -g 스위치와 마찬가지로 컴파일러가 요청할 때 생성되는 디버깅 정보로 제공됩니다. 이 디버깅 정보는 컴파일러에 따라 다양한 형식으로 만들어집니다. 이 정보를 직접 또는 다양한 도구를 사용하여 검사 할 수도 있지만 그렇게하는 방법은 컴파일러 및 사용중인 다른 도구에 따라 다릅니다. 유용하게 사용하려면 디버깅 정보 형식에 대한 많은 연구가 필요합니다.

많은 디버깅 정보는 gdb과 같은 디버거를 사용하여 검사 할 수 있습니다. 디버거는 일반적으로 특정 소스 코드 행과 관련된 지침을 검사하거나 객체에 할당 된 메모리를 찾는 도구를 제공합니다.

그러나 소스 코드에서 실행중인 프로그램의 지침이나 데이터까지의 맵은 매우 복잡 할 수 있습니다. 최적화 프로그램이 불필요하다고 추론했기 때문에 소스 코드의 일부 라인이 완전히 사라 졌을 수 있습니다. 간단한 예를 들어, 고려 :

b = a; 
c = b; 
d = c; 

내가 c = b; 어느 곳에 나 프로그램 명령이 없다고 예상; 나는 컴파일러가 끼어들 수있는 단계없이 d으로 직접 a을 옮기고 상황에 따라 그 방법을 최적화 할 수도 있다고 기대한다.

또한 변수 중 하나와 같은 개체를 처리하는 동안 컴파일러는 레지스터에 개체가 있고 메모리에 전혀없는 코드를 생성 할 수 있으며 메모리에 개체가있는 경우가 있습니다. 객체가 부분적으로 메모리에 있고 부분적으로 레지스터에있을 수도 있습니다. 예를 들어, 객체가 8 바이트로 구성되어 있고 컴파일러가 일부 작업을 수행하는 데 필요한 레지스터 공간을 모두 소모하는 경우 객체의 4 바이트를 스택에 저장하고 새로 사용 가능한 레지스터를 잠시 사용하고 스택.)

5

귀하의 질문은 매우 모호합니다. 컴파일러, 프로세서 또는 운영 체제에 대해서는 언급하지 않았습니다.

자연 상태의 글로벌 변수 (예 : static 변수 및 함수) 만 절대 주소를 가질 수 있습니다.

일반적으로 자동 변수 ("일반"변수)가 스택에 만들어 지므로 변수가 범위에 포함되기 전에 알 수있는 절대 주소가 없습니다.

코드 행에는 확실히 주소가 없으며, 특히 모든 순차적 일 필요는 없습니다. 예를 들어, 일반적인 C for 루프 헤더는 소스 레벨에서 단 한 줄의 코드입니다 :

for(int i = 0; i < n; ++i) 

는 있지만, 그 중 일부는 루프의 신체 일부 이전 후 인으로 확산되는 어셈블리를 생성 할 수 있습니다.

또한 소스 코드의 특정 라인이 특정 양의 기계어 코드를 생성하고, 일부는 컴파일러의 최적화로 인해 사라질 수 있으며, 물론 데이터 선언을 위해서는 보증이 거의 없음을 보장하지 않습니다.

+0

"코드 줄에는 주소가 없습니다." -- 그거 이상 하네; 디버거는 확실히 그렇게 생각합니다. "특정 소스 코드 라인이 특정 양의 기계 코드를 생성한다는 보장은 없습니다"- 관련성이 없습니다. 관련이 있다면 최적화가되면 코드 줄이 산재되어 사라지거나 ... 코드 줄을 추적하려는 경우 최적화하지 마십시오. 추신 "귀하의 질문은 매우 모호합니다."대답을하지 말고 끝내야합니다. –

+1

@JimBalter 나는 그렇게 단순하지 않다라고 생각한다. 나는 그것이 내가 의미하는 것을 더 분명하게하려고 노력했다. 메타 분석을 통해 질문을 개선 할 수있는 기회가 항상 있습니다. – unwind

+0

"나는 그렇게 단순하지 않다고 생각한다."- 분명히 "코드 라인에는 분명히 주소가 없습니다"- 그것은 단순한 무지입니다. 좋은 대답은 디버거에게 코드가 메모리에 어디에 있는지 알려주는 라인 테이블에 대해 이야기합니다. –