2017-09-19 10 views
3

나는 인텔의 정적 코드 분석기 IACA으로 놀아왔다.
같이, 나는 매직 수동으로 바이트를 입력 할 수 있습니다 조립 조각으로 테스트 할 때 그것은 잘 작동 :IACA를 비 어셈블리 루틴과 함께 사용

procedure TSlice.BitSwap(a, b: integer); 
asm 
    //RCX = self 
    //edx = a 
    //r8d = b 

    mov ebx, 111  // Start IACA marker bytes 
    db $64, $67, $90 // Start IACA marker bytes 

    xor eax, eax 
    xor r10d, r10d 

    mov r9d, [rcx] // read the value 
    mov ecx,edx  // need a in cl for the shift 
    btr r9d, edx // read and clear the a bit 

    setc al   // convert cf to bit 
    shl eax, cl  // shift bit to ecx position 

    btr r9d, r8d // read and clear the b bit 

    mov ecx, r8d // need b in ecx for shift 
    setc r10b  // convert cf to bit 
    shl r10d, cl // shift bit to edx position 

    or r9d, eax  // copy in old edx bit 
    or r9d, r10d // copy in old ecx bit 

    mov [r8], r9d // store result 
    ret 

    mov ebx, 222  // End IACA marker bytes 
    db $64, $67, $90 // End IACA marker bytes 
end; 

필요한 매직 마커/접미사 비 어셈블리 코드를 앞에 할 수있는 방법이 있나요 나는 할 수 있도록 컴파일러가 생성 한 코드를 분석 하시겠습니까?

나는 내가 CPU 뷰에서 생성 된 어셈블리를 복사 - 붙여 넣기하고를 사용하여 루틴을 만들 수 있습니다 알고 있지만, 나는

편집
내가 찾고 쉬운 워크 플로우가 기대했다 64 비트 컴파일러에서 작동하는 솔루션 어셈블리와 일반 코드를 32 비트 컴파일러에서 혼합 할 수 있다는 것을 알고 있습니다.

업데이트
@ Dsm의 제안이 작동합니다. @ Rudy의 속임수가 아닙니다.

다음 더미 코드는 작동 :

Throughput Analysis Report 
-------------------------- 
Block Throughput: 13.33 Cycles  Throughput Bottleneck: Dependency chains (possibly between iterations) 

Port Binding In Cycles Per Iteration: 
--------------------------------------------------------------------------------------- 
| Port | 0 - DV | 1 | 2 - D | 3 - D | 4 | 5 | 6 | 7 | 
--------------------------------------------------------------------------------------- 
| Cycles | 1.3 0.0 | 1.4 | 1.0 1.0 | 1.0 1.0 | 0.0 | 1.4 | 2.0 | 0.0 | 
--------------------------------------------------------------------------------------- 

N - port number or number of cycles resource conflict caused delay, DV - Divider pipe (on port 0) 
D - Data fetch pipe (on ports 2 and 3), CP - on a critical path 
F - Macro Fusion with the previous instruction occurred 
* - instruction micro-ops not bound to a port 
^ - Micro Fusion happened 
# - ESP Tracking sync uop was issued 
@ - SSE instruction followed an AVX256/AVX512 instruction, dozens of cycles penalty is expected 
X - instruction not supported, was not accounted in Analysis 

| Num Of |     Ports pressure in cycles      | | 
| Uops | 0 - DV | 1 | 2 - D | 3 - D | 4 | 5 | 6 | 7 | | 
--------------------------------------------------------------------------------- 
| 3^ | 0.3  | 0.3 | 1.0 1.0 |   |  | 0.3 | 1.0 |  | CP | ret 
| X |   |  |   |   |  |  |  |  | | int3 
[... more int3's] 
| X |   |  |   |   |  |  |  |  | | int3 
| 1 | 1.0  |  |   |   |  |  |  |  | | shl eax, 0x10 
| 1 |   | 0.6 |   |   |  | 0.3 |  |  | | cmp eax, 0x64 
| 3^ |   | 0.3 |   | 1.0 1.0 |  | 0.6 | 1.0 |  | CP | ret 
| X |   |  |   |   |  |  |  |  | | int3 
| X |   |  |   |   |  |  |  |  | | int3 
[...] 
Total Num Of Uops: 8 

업데이트 2
이 IACA은 폭탄 것하고 코드를 분석 할 수 없습니다에 호출 문이있는 경우. 불법적 인 지시에 대해 불평 함. 그러나 기본적인 아이디어가 작동합니다. 분명히 초기 ret 및 관련 비용을 뺄 필요가 있습니다.

+0

두 시퀀스 모두 정확히 8 바이트입니다. Can not :'X : = $ 906764000000F6BB' 그리고 루틴 끝에서'X : = $ 906764000000DEBB','X'는'UInt64'입니까? –

+0

기계 코드를 변경할 수 없다면 정적 해석은 무엇입니까?

+0

@RudyVelthuis, 비교를위한 기준선으로 사용. 비 어셈블리 코드는 인라인 될 수 있지만 어셈블리 코드는 인라인 될 수 없습니다. – Johan

답변

4

그래서 나는이 아이디어를 테스트 할 수 없습니다, 그리고 그것이 작동하지 않는 경우에 내가 대답을 삭제합니다,하지만 당신은 단지 같은 것을 할 수없는 IACA를 사용하지 마십시오

procedure TForm10.Button1Click(Sender: TObject); 
begin 
    asm 
    //RCX = self 
    //edx = a 
    //r8d = b 

    mov ebx, 111  // Start IACA marker bytes 
    db $64, $67, $90 // Start IACA marker bytes 
    end; 

    fRotate(fLine - Point(0,1), 23); 

    asm 
    mov ebx, 222  // End IACA marker bytes 
    db $64, $67, $90 // End IACA marker bytes 

    end; 
end; 

이되었다 다른 컴파일러가 컴파일하는 것을 확인하는 샘플 루틴입니다.

슬프게도 이것은 32 비트에서만 작동합니다. 요한은 지적했듯이 64 비트는 허용되지 않습니다.

64 비트의 경우 다음과 같이 작동 할 수 있지만 다시 테스트 할 수는 없습니다.

procedure TForm10.Button1Click(Sender: TObject); 
    procedure Test1; 
    asm 
    //RCX = self 
    //edx = a 
    //r8d = b 

    mov ebx, 111  // Start IACA marker bytes 
    db $64, $67, $90 // Start IACA marker bytes 
    end; 
    procedure Test2; 
    begin 
    fRotate(fLine - Point(0,1), 23); 
    end; 
    procedure Test3; 
    asm 
    mov ebx, 222  // End IACA marker bytes 
    db $64, $67, $90 // End IACA marker bytes 

    end; 
begin 
    Test1; 
    Test2; 
    Test3; 
end; 
+0

IACA의 최신 버전은 x64에서만 작동합니다. 64 비트 컴파일러에서는 어셈블리와 일반 코드를 혼합 할 수 없습니다. IACA의 32 비트 및 이전 버전에서 작동합니다. – Johan

+0

@Johan 부적절한 버전의 코드를 수정했습니다. 귀하의 요구에 너무 복잡하게 얽혀 있는지 알 수 없습니다. – Dsm

+0

루틴의 시작 부분에 관계없는 "ret"및 일부 정렬 코드가 있지만 아주 잘 작동 할 수 있습니다. – Johan