转储GCC中的寄存器值

我需要使用GCC获取寄存器中的值。

类似这样的东西:

EAX=00000002  EBX=00000001  ECX=00000005  EDX=BFFC94C0
ESI=8184C544  EDI=00000000  EBP=0063FF78  ESP=0063FE3C
CF=0  SF=0  ZF=0  OF=0

获取32位寄存器非常简单,但我不确定获取标志的最简单方法是什么。

在本书的例子中:http://kipirvine.com/asm/

他们通过获得整个EFLAGS寄存器并转移相关位来完成。 我也想过使用Jcc和CMOVcc来做。

任何其他建议如何做到这一点? 一些要验证的测试用例也是有用的。


不需要使用汇编程序来获取寄存器。

你可以使用setjmp。 这会将所有寄存器写入类型为jmp_buf的结构。 它甚至可以跨平台工作,除了jmp_buf本身对于每个体系结构都不同的事实。

但是,调用setjmp(并调用汇编代码)会改变一些寄存器,所以你不能真正相信它们。

有一种方法可以获得真实的快照,但这有点困难并且取决于操作系统:

  • 为非法非法操作码扩展安装一个异常处理程序。 处理程序可以是一个真正的中断,一个信号处理程序或一个操作系统异常处理程序(try / except块形式的C ++将不起作用)。

  • 在您的代码中发出非法操作码。

  • 这里的技巧是,非法操作码没有寄存器副作用。 异常处理程序可以从堆栈或异常信息结构中复制寄存器。

    同样的技巧可以用于断点中断强制溢出,陷阱等等。 通常有多种方法可以从一段代码中引发中断。


    关于EFLAGS:您可以通过堆栈操作获取它们:

      PUSHFD
      POP EAX  
      , eax now contains the EFLAG data
    

    恕我直言,使用gdb比gcc好。

    http://www.unknownroad.com/rtfm/gdbtut/gdbadvanced.html

    HTH


    以下是针对64位机器的测试。 如果你有一个32位的机器,删除64位齿轮,并改变flag64 - > flag32(并使用pushfd而不是pushfq )。 在实践中,我发现我只需要检查标志寄存器中的CY(进位)和OV(溢出)(我通常使用jcjncjojno )。

    #include <stdio.h>
    #include <stdint.h>
    
    #define HIGH32(x) ((uint32_t)(((uint64_t)x)>>32))
    #define LOW32(x) ((uint32_t)(((uint64_t)x)& 0xFFFFFFFF))
    
    int main(int argc, char** argv)
    {
        uint32_t eax32, ebx32, ecx32, edx32;
        uint64_t rax64, rbx64, rcx64, rdx64;
    
        asm (
             "movl %%eax, %[a1] ;"
             "movl %%ebx, %[b1] ;"
             "movl %%ecx, %[c1] ;"
             "movl %%edx, %[d1] ;"
    
             "movq %%rax, %[a2] ;"
             "movq %%rbx, %[b2] ;"
             "movq %%rcx, %[c2] ;"
             "movq %%rdx, %[d2] ;"
             :
             [a1] "=m" (eax32), [b1] "=m" (ebx32), [c1] "=m" (ecx32), [d1] "=m" (edx32), 
             [a2] "=m" (rax64), [b2] "=m" (rbx64), [c2] "=m" (rcx64), [d2] "=m" (rdx64)
             );
    
        printf("eax=%08xn", eax32);
        printf("ebx=%08xn", ebx32);
        printf("ecx=%08xn", ecx32);
        printf("edx=%08xn", edx32);
    
        printf("rax=%08x%08xn", HIGH32(rax64), LOW32(rax64));
        printf("bax=%08x%08xn", HIGH32(rbx64), LOW32(rbx64));
        printf("cax=%08x%08xn", HIGH32(rcx64), LOW32(rcx64));
        printf("dax=%08x%08xn", HIGH32(rdx64), LOW32(rdx64));
    
        uint64_t flags;
    
        asm (
             "pushfq        ;"
             "pop %[f1] ;"
             :
             [f1] "=m" (flags)
             );
    
        printf("flags=%08x%08x", HIGH32(flags), LOW32(flags));
    
        if(flags & (1 << 0)) // Carry
            printf(" (C1"); 
        else
            printf(" (C0");
    
        if(flags & (1 << 2)) // Parity
            printf(" P1");
        else
            printf(" P0");
    
        if(flags & (1 << 4)) // Adjust
            printf(" A1");
        else
            printf(" A0");
    
        if(flags & (1 << 6)) // Zero
            printf(" Z1");
        else
            printf(" Z0");
    
        if(flags & (1 << 7)) // Sign
            printf(" S1");
        else
            printf(" S0");
    
        if(flags & (1 << 11)) // Overflow
            printf(" O1)n");
        else
            printf(" O0)n");
    
        return 0;
    }
    
    链接地址: http://www.djcxy.com/p/85901.html

    上一篇: Dumping the values of the registers in GCC

    下一篇: Any advantage of XOR AL,AL + MOVZX EAX, AL over XOR EAX,EAX?