Генерация машинного кода из C

Извините, если это наивные вопросы - я очень плохо понимаю, как C действительно работает на низком уровне.

Итак, я генерирую машинный код для записи в некоторую память mmap для выполнения. Меня смущает использование шестнадцатеричных литералов для генерации машинного кода.

Рассмотрим инструкцию по сборке (синтаксис AT&T): cmove %edx, %ecx. Это представление машинного кода 0x0F44CA.

Итак, сделал бы что-то вроде:

char opcode[3] { 0x0F, 0x44, 0xCA };

представлять правильную двоичную строку в разделе, когда «под капотом»? Я подозреваю, что это не так, поскольку шестнадцатеричные литералы в C, по-видимому, хранятся как целые числа. Меня беспокоит то, что, поскольку целые числа являются 32-битными, фактические значения сохраняются

0x0000000F 0x00000044 0x000000CA

Что-то совершенно отличное от того, что мне нужно.

Еще одна проблема, которую я беспокою, заключается в том, влияет ли тип, который я даю массиву, на фактически сохраняемое значение? Так бы

uint8_t opcode[3] { 0x0F, 0x44, 0xCA };

or

int opcode[3] { 0x0F, 0x44, 0xCA };

отличаться от

char opcode[3] { 0x0F, 0x44, 0xCA };

под капотом?


person AlexJ136    schedule 20.08.2013    source источник
comment
Меня беспокоит то, что, поскольку целые числа являются 32-разрядными... Будьте более конкретными. На вашей платформе int и unsigned int скорее всего 32-разрядные. Хорошо, что char opcode[3] не является массивом int. Но ваша вторая проблема верна, и я предлагаю провести дополнительные исследования (начните с этого).   -  person WhozCraig    schedule 20.08.2013
comment
Я понимаю, что это придирки, но во всех ваших инициализациях массивов отсутствует = между ] и {. Думайте об инициализациях как о присваиваниях.   -  person unwind    schedule 20.08.2013
comment
Шестнадцатеричные литералы никак не сохраняются. Это просто исходный код.   -  person harold    schedule 06.09.2013


Ответы (2)


uint8_t opcode[3] = { 0x0F, 0x44, 0xCA };

будут хранить ваши значения как 8-битные значения «байты» в том порядке, в котором вы их указали.

Это то же самое, что

unsigned char opcode[3] = { 0x0F, 0x44, 0xCA };

Но использование типа «int», как вы сказали, 0000000F00000044000000CA или 0F00000044000000CA000000 в зависимости от порядка байтов вашей системы.

person rockdaboot    schedule 20.08.2013
comment
Именно то, что мне нужно было знать. Спасибо. - person AlexJ136; 20.08.2013

Я не понял вашей реальной проблемы, но я думаю, что эти два пункта могут помочь вам лучше понять машинный код.

  1. Используйте objdump, и вы соберете machine code и assembly code вместе, чтобы понять, что происходит.

    objdump -d prog.o
    
  2. Прочтите эту статью http://csapp.cs.cmu.edu/public/ch3-preview.pdf

Я надеюсь, что это поможет вам немного.

person someone    schedule 20.08.2013