Отображение последовательности команд (сборки) в код на C

Из моего учебника есть одно упражнение:

int comp(data_t a, data_t b) {
    return a COMP b;
}

показывает общее сравнение между аргументами a и b, где мы можем установить тип данных аргументов, объявив data_t с объявлением typedef, и мы можем установить сравнение, определив COMP с объявлением #define. Предположим, a в%edx, а b в%eax. Для каждой из следующих последовательностей команд определите, какие типы данных data_t (может быть несколько правильных ответов; вы должны перечислить их все.)

cmpl %eax, %edx
setl %al

И ответ из учебника:

Суффикс 'l' и идентификаторы регистра указывают 32-битные операнды, в то время как сравнение для дополнения до двух '<'. Мы можем сделать вывод, что data_t должно быть int.

поэтому мой вопрос: поскольку он просит перечислить все возможные ответы, почему data_t также не может быть long long и указателем, которые также являются 32-битными?

1 ответ

Очень конкретный ответ на ваш очень конкретный вопрос заключается в том, что long не имеет определения фиксированного размера. Когда вышли первые 32-разрядные процессоры x86 и начался переход с 16 на 32 бита, для ряда компиляторов int изменился с 16 на 32 бита. Но long int остался на 32 битах. И это продолжалось до тех пор, пока не появились 64-битные процессоры x86, а некоторые популярные компиляторы изменили длину на 64-битную, а int остался 32-битной.

Но определение того, какой бит int или long - это выбор автора компилятора, для описания этого в спецификации языка используется термин "определенная реализация". Поэтому вполне возможно, что одна версия компилятора или компилятора одного и того же компилятора интерпретирует длину 32 бита, а другая версия компилятора или той же версии интерпретирует длину 64 бита для одной и той же цели. Вот откуда взялся stdint.h, это что-то вроде хака, но, учитывая возраст и историю языка Си и множество компиляторов, у них не было большого выбора.

Теперь, если вы продемонстрируете выходные данные компилятора, вы можете / обнаружите, что некоторые компиляторы используют регистры большего размера eax/rax и избегают операций al/bl ah/bl, что частично связано с микрокодированием и производительностью. Итак, cmpl и eax/edx расскажут вам о начале истории. Прочтите эту документацию по ассемблеру прямо на языке ассемблера (языки ассемблера определяются ассемблером, инструментом, а не разработчиком чипа / логики, хотя они часто будут в основном напоминать документация производителя чипа /ip). А затем учтите возможность того, что некоторые копмилеры могут использовать ту же конкретную инструкцию для переменных меньшего размера (но, конечно, не большего размера).

Но эта сборка не соответствует предоставленному коду C, если только определение int не является 8 битами. Учебник подразумевает определение целого числа 32 бита. Так что это ужасный и очень сломанный пример. Если остальная часть учебника такая, я желаю вам удачи. x86 - неправильный первый набор инструкций для обучения, его никогда не следует использовать для преподавания такого рода темы. многие / большинство других будут служить вам лучше. Я уверен, что у вас, вероятно, нет выбора, поэтому ваша задача намного сложнее.

Что вы можете / должны сделать, это взять этот код, взять ваш компилятор или компиляторы и предоставить определения для data_t и COMP и посмотреть, что вы получите. _T в коде C подразумевает знание stdint.h, поэтому используйте эти определения для своего тестового кода и своего ответа на это домашнее задание.

Другие вопросы по тегам