can someone explain this short segment of C++ code, I can't make heads or tails of it

前端 未结 2 1583
南方客
南方客 2021-01-25 14:42
#include 
const char *getOpcodeName(
    uint8_t op
)
{
    #define OPCODE(x, y) if((0x##y)==op) return "OP_" #x;
        OPCODES
    #undef O         


        
相关标签:
2条回答
  • 2021-01-25 15:28

    Short answer: This function converts opcodes to string.

    The * IS RELATED to do with pointers! in fact, this function returns a const char * type. This is a pointer for a char buffer (in this case) used to point to a C-String. Every C-String is actually a buffer with "readable characteres" (alphanumerical, some accents, basic symbols + some stuff) followed by a byte of value 0 (or '\0') to indicate the end of the string!

    This function converts opcodes (assembly instructions) to a readable string. So The intention of the programmer was to transform:

    • 0x01 -> OP_CODE1
    • 0x02 -> OP_CODE2
    • 0x03 -> OP_CODE3

    The expanded version of the code is something like this:

    const char *getOpcodeName( uint8_t op )
    {
        if((0x01)==op) return "OP_X";
        if((0x02)==op) return "OP_Y";
        if((0x03)==op) return "OP_Z";
        ...
        if((0x??)==op) return "OP_?";
        return "OP_UNKNOWN";
    }
    

    Insted of write houndreds of IF's ... the programmer decided to create the macro

    #define OPCODE(x, y) if((0x##y)==op) return "OP_" #x;
    

    So it's possible to write the OPCODES table easily like this:

    #define OPCODES \
    OPCODE( 01, "X" ) \
    OPCODE( 02, "Y" ) \
    OPCODE( 03, "Z" ) \
    ...
    OPCODE( ??, "?" )
    

    Opcodes are codes that indentify the processor instruction (assembly instructions). Example of real instructions (for some Intel processor) are:

      inc eax      ; opcode = 0x40
      pusha        ; opcode = 0x60
      nop          ; opcode = 0x90
    

    So your table could be:

    #define OPCODES \
    OPCODE( 40, "INCEAX" ) \
    OPCODE( 60, "PUSHA" ) \
    OPCODE( 90, "NOP" )
    
    0 讨论(0)
  • 2021-01-25 15:40

    Run your code thru a C++ preprocessor, e.g. using g++ -Wall -C -E opcodes.cpp > opcodes.i then look inside the generated opcodes.i

    #define is not a statement but a preprocessor directive.

    The macro OPCODES gets expanded to some big chunk, notably containing OPCODE( NOP, 61) which would get expanded to something like

    if ((0x61)==op) return "OP_" "NOP";
    

    The two string literals are concatenated into one, "OP_NOP" here.

    GCC has a good documentation on its cpp preprocessor. Read about stringification (with the single # like the ending #x; of the OPCODE macro) and about concatenation (with a double ## like (0x##y) of the OPCODE macro).

    0 讨论(0)
提交回复
热议问题