asm을 많이 다루고 GDB에서 레지스터와 메모리를 살펴 보는 C 책을 읽었습니다. 정확히 동일한 소스를 컴파일 및 디스 어셈블 할 때 (실제로 책 CD와 함께 제공된 소스 파일을 사용하여) 어셈블리의 지시 사항이 책의 내용과 약간 다릅니다. 이 책은 intel flavored 어셈블리를 사용하고 gdb에 "set disassembly intel"을 넣으므로 그렇게하지 않습니다. 지시 사항의 순서가 다르며 일부는 모두 다르고 다른 몇 가지 단점이 있습니다.gdb의 이상한 결과
예컨대이 책에 MOV 상기 EIP 레지스터의 지시가 : for 루프에서, 변수 I를 0으로 초기화 대응
(gdb) x/i $eip
mov DWORD PTR[ebp-4], 0x0
(I = 0, i가 < 10 난 ++
(gdb) x/i $eip
mov DWORD PTR[esp+0x1c], 0x0
통지는 다른 레지스를 참조 할 것 :이 참조) 실행)
그러나, 같은 장소에서 중단 점 내 GDB 콘솔에서 (주 휴식 설정 ter 모두 함께 - ebp 대신 esp esp의 값을 확인하면 0x1c 자체입니다. 하지만 0x1c 또는 esp + 0x1c에있는 항목을 검사하려고하면 그 주소를 볼 수 없다고 알려줍니다.
그래서 책이 계속 진행됨에 따라 나는 따라갈 수 없습니다. ebp, ebp-4 등의 흔적을 따라 가며 ebp 레지스터에서 아무 것도 일어나지 않는 것 같습니다.
이 책은 2008 년에 작성되었으므로 gcc 또는 gdb의 버전 변경으로 인해 변경 사항이 상당 부분 도입 될 것이라고 상상해보십시오 (또는 그랬습니까?) ... 일부 컴파일러 최적화 또는 기본적으로 다른 결과를 생성하는 스위치가있을 수 있습니다 ?
미리 감사드립니다.
편집 : Strange. 나는 각각의 제안을 시도했지만 아무 것도 효과가 없었다. 그런 다음 나는 rm a.out을했고 새로 컴파일되었고 이제는 잘 작동한다. (지침은 여전히 책과 다르지만 책의 주소와 일치하는 주소를 조사 할 수있다. 내가 상응하는 패턴을 따라갈 수 있다면, 정확히 똑같은 크기 일 필요는 없습니다. 너무 간단 할 것입니다!) 여러분의 도움과 제안에 다시 한번 감사드립니다.
감사합니다. 이 책은 32 비트 인텔을 사용하고 있습니다. 둘 다 gcc로 컴파일하고 (버전을 확인하고 qeustion을 업데이트해야합니다), 리눅스를 실행해야합니다. 이 책은 우분투 (다시 버전을 확인해야합니다)를 기반으로하고 최신 아치 설치를 실행하고 있습니다. 동일한 아키텍처와 동일한 컴파일러 (gcc)를 사용한다고 가정한다면 동일한 기계 코드가 필요합니까? 어느 쪽이든, 나는 그 값이 내가 조사 할 수없는 주소로 초기화되고 이상하게도 $ esp 즉 스택 포인터에 의해 참조되고 있다는 것을 알게된다. – speakingcode
아니야, 같은 이유가 될 이유가 없다. . '-O0' 또는'-march = i386'으로 재생할 수 있습니다. 그러나 그것이 완전히 다른 것은 놀라운 일이 아닙니다. –