program story

Visual C ++를 사용하여 코드 뒤의 어셈블리를 보는 방법은 무엇입니까?

inputbox 2020. 8. 9. 10:25
반응형

Visual C ++를 사용하여 코드 뒤의 어셈블리를 보는 방법은 무엇입니까?


나는 두 줄의 코드의 효율성에 관한 또 다른 질문을 읽고 있었고 OP는 그가 코드 뒤의 어셈블리를 보았고 두 줄이 어셈블리에서 동일하다고 말했습니다. 여담을 제외하고, 프로그램이 컴파일 될 때 생성 된 어셈블리 코드를 어떻게 볼 수 있습니까?

Microsoft의 Visual C ++를 사용하고 있지만 Visual Basic으로 작성된 코드 뒤에있는 어셈블리를 볼 수 있는지도 알고 싶습니다.

그렇다면 C ++ 및 Visual Basic과 같은 고급 언어로 작성된 프로그램 뒤에있는 어셈블리 코드를 어떻게 볼 수 있습니까?


몇 가지 접근 방식이 있습니다.

  1. Visual Studio (및 Eclipse도)에서 C ++를 디버깅하는 동안 일반적으로 어셈블리 코드를 볼 수 있습니다. 이를 위해 Visual Studio에서 문제의 코드에 중단 점을 설정하고 디버거가이를 때리면 클릭하고 "어셈블리로 이동"을 찾습니다 (또는 CTRL + ALT + D를 누릅니다).

  2. 두 번째 방법은 컴파일하는 동안 어셈블리 목록을 생성하는 것입니다. 이를 위해 프로젝트 설정-> C / C ++-> 출력 파일-> ASM 목록 위치로 이동하여 파일 이름을 입력합니다. 또한 "Assembly Output"에서 "Assembly With Source Code"를 선택합니다.

  3. 프로그램을 컴파일하고 타사 디버거를 사용하십시오. 이를 위해 OllyDbg 또는 WinDbg를 사용할 수 있습니다. 또한 IDA (대화 형 디스어셈블러)를 사용할 수 있습니다. 그러나 이것은 그것을하는 하드 코어 방법입니다.


추가 참고 사항 : 디버그 어셈블러 출력과 릴리스 1 사이에는 큰 차이가 있습니다. 첫 번째는 컴파일러가 C ++에서 어셈블러 코드를 생성하는 방법을 배우는 데 좋습니다. 두 번째는 컴파일러가 다양한 C ++ 구문을 최적화하는 방법을 배우는 데 좋습니다. 이 경우 일부 C ++에서 asm으로의 변환이 명확하지 않습니다.


cl 컴파일러에 대해 / FA 스위치를 지정합니다. 스위치의 값에 따라 어셈블리 코드 또는 고급 코드와 어셈블리 코드 만 통합됩니다. 파일 이름은 .asm 파일 확장자를 갖습니다. 지원되는 값은 다음과 같습니다.


  • / FA 어셈블리 코드; .asm
  • / FAc 기계 및 조립 코드; .대구
  • / FAs 소스 및 어셈블리 코드; .asm
  • / FAcs 기계, 소스 및 어셈블리 코드; .대구

가장 쉬운 방법은 디버거를 실행하고 디스 어셈블리 창을 확인하는 것 입니다.


이 답변의 이전 버전 (rextester.com의 "해킹")은 http://gcc.godbolt.org/ 에서 ARM, x86 및 x86-64 용 CL 19 RC제공 하므로 대부분 중복됩니다 (Windows 호출 규칙을 대상으로 함). , 해당 사이트의 gcc, clang 및 icc와 달리).

Godbolt 컴파일러 탐색기는 컴파일러 asm 출력을 멋지게 형식화하고 지시문의 "노이즈"를 제거하도록 설계되었으므로 인수를 취하고 값을 반환하는 간단한 함수에 대해 asm을 살펴볼 때 사용하는 것이 좋습니다 (그러므로 최적화).

잠시 동안 CL은 http://gcc.beta.godbolt.org/ 에서 사용할 수 있었지만 메인 사이트는 아니었지만 지금은 둘 다에 있습니다.


http://rextester.com/l/cpp_online_compiler_visual 온라인 컴파일러 에서 MSVC asm 출력을 얻으려면 : /FAs명령 줄 옵션에 추가 합니다. 프로그램이 자체 경로를 찾고 경로를 찾아서 .asm덤프하도록하십시오. 또는 .exe.

예 : http://rextester.com/OKI40941

#include <string>
#include <boost/filesystem.hpp>
#include <Windows.h>

using namespace std;

static string my_exe(void){
    char buf[MAX_PATH];
    DWORD tmp = GetModuleFileNameA( NULL, // self
                                  buf, MAX_PATH);
    return buf;
}

int main() {
    string dircmd = "dir ";
    boost::filesystem::path p( my_exe() );
    //boost::filesystem::path dir = p.parent_path();

    // transform c:\foo\bar\1234\a.exe 
    // into      c:\foo\bar\1234\1234.asm
    p.remove_filename();
    system ( (dircmd + p.string()).c_str() );

    auto subdir = p.end();      // pointing at one-past the end
    subdir--;                   // pointing at the last directory name
    p /= *subdir;               // append the last dir name as a filename
    p.replace_extension(".asm");
    system ( (string("type ") + p.string()).c_str() );
//    std::cout << "Hello, world!\n";
}

... code of functions you want to see the asm for goes here ...

type의 DOS 버전입니다 cat. asm을보고 싶은 함수를 찾기 어렵게 만드는 더 많은 코드를 포함하고 싶지 않았습니다. (그 목표에 표준 : : 문자열과 부스트 런 카운터를 사용하지만!이 처리 (그리고있어 문자열에 대한 자세한 가정을 일부 C 스타일의 문자열 조작의 결과에) 큰 버퍼를 사용하여 최대 길이 안전 / 할당을 무시 GetModuleFileNameA겠습니까 전체 기계 코드가 훨씬 적습니다.)

IDK why, but cout << p.string() << endl only shows the basename (i.e. the filename, without the directories), even though printing its length shows it's not just the bare name. (Chromium48 on Ubuntu 15.10). There's probably some backslash-escape processing at some point in cout, or between the program's stdout and the web browser.


In Visual C++ the project options under, Output Files I believe has an option for outputing the ASM listing with source code. So you will see the C/C++ source code and the resulting ASM all in the same file.


For MSVC you can use the linker.

link.exe /dump /linenumbers /disasm /out:foo.dis foo.dll

foo.pdb needs to be available to get symbols


Red Gate's .NET Reflector is a pretty awesome tool that has helped me out more than a few times. The plus side of this utility outside of easily showing you MSIL is that you can analyze a lot of third-party DLLs and have the Reflector take care of converting MSIL to C# and VB.

I'm not promising the code will be as clear as source but you shouldn't have much trouble following it.

참고URL : https://stackoverflow.com/questions/1020498/how-to-view-the-assembly-behind-the-code-using-visual-c

반응형