GCC를 사용하여 읽을 수 있는 어셈블리를 만들고 있습니까?
C 소스 파일의 GCC를 사용하여 머신 코드의 니모닉 버전을 덤프하여 코드가 컴파일된 것을 확인할 수 있도록 하는 방법을 생각하고 있었습니다.Java로 할 수 있는데 GCC로 할 수 있는 방법이 없어요.
조립 시 C 방식을 다시 작성하려고 하는데 GCC가 어떻게 되는지 확인하면 큰 도움이 될 것 같습니다.
기호를 경우(「」를 추가합니다).-g
수 있습니다(를 사용하는 에도 마찬가지입니다.-O3
1)를 사용할 수 있습니다.objdump -S
C 소스와 인터리브된 보다 읽기 쉬운 분해 기능을 제공합니다.
>objdump --help
[...]
-S, --source Intermix source code with disassembly
-l, --line-numbers Include line numbers and filenames in output
objdump -drwC -Mintel
습니니다
-r
시 시 심볼명이puts
call
다음 절차)-R
, 스탭의 라이브러리의 )을 나타냅니다.-C
C C++ 심볼명-w
바이트를 "wide"로 줄 머신 코드 바이트의 회선 변환은 이루어지지 않습니다.-Mintel
/ MASM : GAS / Binutils MASM.intel_syntax noprefix
AT& 닌 at at at-S
: 소스 회선을 디스어셈블리와 함께 인터리브합니다.
것도 수 요.alias disas="objdump -drwCS -Mintel"
안에서~/.bashrc
이 경우 AT구문을 x86 의 AT&T 의 AT&T 의 구문을 -Mintel
.
예:
> gcc -g -c test.c
> objdump -d -M intel -S test.o
test.o: file format elf32-i386
Disassembly of section .text:
00000000 <main>:
#include <stdio.h>
int main(void)
{
0: 55 push ebp
1: 89 e5 mov ebp,esp
3: 83 e4 f0 and esp,0xfffffff0
6: 83 ec 10 sub esp,0x10
puts("test");
9: c7 04 24 00 00 00 00 mov DWORD PTR [esp],0x0
10: e8 fc ff ff ff call 11 <main+0x11>
return 0;
15: b8 00 00 00 00 mov eax,0x0
}
1a: c9 leave
1b: c3 ret
주의: 이것은 다음 명령어를 사용하지 않습니다.-r
에, so socall rel32=-4
않습니다.puts
부서진 것 같아요.call
이치노 때 주의해 주세요.rel32
콜 부호화의 변위는 링커가 실제 오프셋을 채울 때까지(이 경우 libc를 스태틱하게 링크하지 않는 한) 플레이스 홀더일 뿐입니다.
각주 1: 인터리빙 소스는 복잡하고 최적화된 빌드에 그다지 도움이 되지 않을 수 있습니다.그러기 위해서는 https://godbolt.org/ 또는 어떤 명령이 어떤 소스 라인에 적용되는지 시각화하는 다른 방법을 고려하십시오.최적화된 코드에서는 명령을 설명하는 단일 소스 행이 항상 있는 것은 아니지만 디버깅 정보는 각 asm 명령에 대해 하나의 소스 행을 선택합니다.
GCC에 플래그를 주면-fverbose-asm
것이다.
생성된 어셈블리 코드에 추가 주석 정보를 넣어 가독성을 높입니다.
[...] 추가된 설명은 다음과 같습니다.
- 컴파일러 버전 및 명령줄 옵션에 대한 정보
- 조립 지침과 관련된 소스 코드 행은 FILENAME:LINENUMBER:CONTE OF LINE 형식으로,
- 어떤 고급 표현이 다양한 어셈블리 명령 피연산자에 해당하는지에 대한 힌트입니다.
-S(주: 대문자 S) 스위치를 GCC에 사용하면 .s 확장자를 가진 파일로 어셈블리코드를 내보냅니다.예를 들어 다음 명령어가 있습니다.
gcc -O2 -S foo.c
생성된 어셈블리 코드를 foo 파일에 남깁니다.
http://www.delorie.com/djgpp/v2faq/faq8_20.html에서 바로 리핑(오류 삭제)-c
)
「 」의 -S
로 AT되며, 는 x86 GCC에서 AT&T로 할 수 .AT&T-masm=att
바꿔치기하다.
gcc -S -masm=att code.c
구문으로 「」를 할 수 .-masm=intel
바꿔치기하다.
gcc -S -masm=intel code.c
다 덤프를 합니다.code.c
, 파일, 파일, 파일, 파일, 파일, 파일, 파일,code.s
□□□□□□□□★
objdump를 하는 것이 .--disassembler-options=
intel
/att
스위치, 예(구문의 차이를 나타내기 위한 코드 덤프 포함):
$ objdump -d --disassembler-options=att code.c
080483c4 <main>:
80483c4: 8d 4c 24 04 lea 0x4(%esp),%ecx
80483c8: 83 e4 f0 and $0xfffffff0,%esp
80483cb: ff 71 fc pushl -0x4(%ecx)
80483ce: 55 push %ebp
80483cf: 89 e5 mov %esp,%ebp
80483d1: 51 push %ecx
80483d2: 83 ec 04 sub $0x4,%esp
80483d5: c7 04 24 b0 84 04 08 movl $0x80484b0,(%esp)
80483dc: e8 13 ff ff ff call 80482f4 <puts@plt>
80483e1: b8 00 00 00 00 mov $0x0,%eax
80483e6: 83 c4 04 add $0x4,%esp
80483e9: 59 pop %ecx
80483ea: 5d pop %ebp
80483eb: 8d 61 fc lea -0x4(%ecx),%esp
80483ee: c3 ret
80483ef: 90 nop
그리고.
$ objdump -d --disassembler-options=intel code.c
080483c4 <main>:
80483c4: 8d 4c 24 04 lea ecx,[esp+0x4]
80483c8: 83 e4 f0 and esp,0xfffffff0
80483cb: ff 71 fc push DWORD PTR [ecx-0x4]
80483ce: 55 push ebp
80483cf: 89 e5 mov ebp,esp
80483d1: 51 push ecx
80483d2: 83 ec 04 sub esp,0x4
80483d5: c7 04 24 b0 84 04 08 mov DWORD PTR [esp],0x80484b0
80483dc: e8 13 ff ff ff call 80482f4 <puts@plt>
80483e1: b8 00 00 00 00 mov eax,0x0
80483e6: 83 c4 04 add esp,0x4
80483e9: 59 pop ecx
80483ea: 5d pop ebp
80483eb: 8d 61 fc lea esp,[ecx-0x4]
80483ee: c3 ret
80483ef: 90 nop
godbolt는 매우 유용한 도구입니다. 목록에는 C++ 컴파일러만 포함되어 있지만 사용할 수 있습니다.-x c
C로 하다되어 '하다'를 할 수 .Colourise
생성된 어셈블리에 매핑되는 소스 코드를 시각적으로 나타내는 색상 막대를 생성하는 옵션입니다.예를 들어 다음과 같은 코드입니다.
#include <stdio.h>
void func()
{
printf( "hello world\n" ) ;
}
다음 명령줄을 사용합니다.
-x c -std=c99 -O3
★★★★★★★★★★★★★★★★★」Colourise
는 다음과같은 합니다.
해보셨어요?gcc -S -fverbose-asm -O source.c
생성된 데이터를 조사합니다.source.s
★★★★★★★★★★★★★★★★★?
된 어셈블러 는 '어셈블러 코드'에 .source.s
할 수 ).-o
assembler-param);-fverbose-asm
옵션은 컴파일러가 생성된 어셈블러 코드를 설명하는 어셈블러 코멘트를 내보내도록 요구합니다.-O
합니다('비트를 하다'로 최적화할 수 ).-O2
★★★★★★★★★★★★★★★★★」-O3
를 참조해 주세요.
뜻인지 알고 gcc
입니다.-fdump-tree-all
하지만 조심해요 수백 개의 덤프 파일이 있을 거예요
BTW, GCC는 플러그인 또는 MELT(GCC 확장을 위한 고급 도메인 고유 언어, 2017년에 포기)를 통해 확장 가능
여기에는 objdump와 같이 gdb를 사용할 수 있습니다.
이 발췌문은 http://sources.redhat.com/gdb/current/onlinedocs/gdb_9.html#SEC64 에서 발췌한 것입니다.
다음은 인텔 x86의 혼합 소스+어셈블리 예시입니다.
(gdb) disas /m main함수 메인 어셈블러 코드 덤프: 5 {0x08048330 : %ebp 푸시0x08048331 : mov %param, %ebp0x08048333 : 0x8달러 미만, %subs0x08048336 :및 $0xffffff0,%sg0x08048339 : $0x10 미만, %gg 6 printf("Hello.\n");0x0804833c : movl $0x8048440, (%pair)0x08048343 : 콜 0x8048284 7 리턴 0;8 }0x08048348 : mov 0x0,%eax0x0804834d : 탈퇴0x0804834e : ret 어셈블러 덤프의 끝입니다.
-S(주: 대문자 S) 스위치를 GCC에 사용하면 .s 확장자를 가진 파일로 어셈블리코드를 내보냅니다.예를 들어 다음 명령어가 있습니다.
gcc - O2 - S - c foo.c
못 맞혔어gcc
,의 ,g++
하다
-g
debug-Wa,-adhln
는, 코드와 을 표시하기 .
g++ -g -Wa,-adhln src.cpp
gcc 또는 g++ 옵션으로서 -Wa,-adhln을 사용하여 stdout에 대한 목록 출력을 생성합니다.
-Wa,...는 어셈블러 부품의 명령줄 옵션용입니다(C/++ 컴파일 후 gcc/g++로 실행).내부에서 호출됩니다(Windows에서는 as.exe).봐
> --도움말로서
gcc 내의 어셈블러 도구에 대한 자세한 도움말을 보려면 명령줄로 사용합니다.
언급URL : https://stackoverflow.com/questions/1289881/using-gcc-to-produce-readable-assembly
'programing' 카테고리의 다른 글
정적으로 연결된 라이브러리 간에 심볼 충돌을 처리하는 방법은 무엇입니까? (0) | 2022.08.16 |
---|---|
여러 연결을 할 때 C에서 소켓타임아웃을 설정하려면 어떻게 해야 합니까? (0) | 2022.08.16 |
vuejs v2.0에서 컴포넌트로 데이터 전달 (0) | 2022.08.09 |
Requirejs에서 Vue.js를 사용하는 방법 (0) | 2022.08.09 |
Java에서 int를 char로 변환 (0) | 2022.08.09 |