Реферат: Взаимосвязь языков C и ассемблера
inc [ i ]
;
;--Код, использующий локальную переменную [i]
;
cmp [i], 10
jne @@10
mov sp, bp
pop bp
ret ; Возврат в точку вызова
ENDP _cfunction
Директива LOCAL в этом примере подготавливает переменную i типа Word (слово). Указание = stacksize назначает общее число байтов, занимаемое всеми локальными переменными - в данном случае 2 байта. Это значение вычитается из sp после подготовки адресации переменных в стек. Затем, для ссылки на i, используются такие инструкции, как mov, inc и crop. Благодаря директиве LOCAL ссылки типа [i] переводятся следующим образом:
mov [bp-2], 0
inc [bp-2]
и т.д. При использовании LOCAL нет необходимости вычислять отрицательные смещения относительно bp, чтобы определить местоположение переменных в стеке, -достаточно воспользоваться именами переменных.
Поскольку bp не изменяется во время выполнения этой функции, можно восстановить sp по средством bp, удаляя область локальной переменной из стека, или прибавить stacksize к sp с помощью команды
add sp, stacksize
Подходят оба метода, но восстановление sp посредством bp - быстрее. Можно также объявить несколько локальных переменных операторами, подобными следующему:
LOCAL i:Word; j:Word; c:Byte=stacksize
Теперь, после вычитания stacksize из указателя стека для резервирования области в стеке, можно использовать три локальные переменные - i, j и с. (Необходимо всегда делать LOCAL, что упрощает адресацию локальных переменных, это не создает область для переменных в памяти.)
4.3 Передача аргументов
Совместное использование C++ и ассемблера становится более сложным, когда к функциям добавляются аргументы. Приходится очень внимательно программировать, обращаясь к функциям из различных модулей и выбирая аргументы из стека. Но следующая директива берет на себя задачу сама произвести ломку имен и занести их в стек:
ARG c_offset:byte, k_pffset:word
Аргументы, перечисленные таким образом, не являются объектами данных; они смещаются в стеке относительно регистра bр. Использование ARG подобным образом позволяет ассемблеру вычислить смещения вместо нас - но мы должны специфицировать правильные типы данных. Символьная переменная в C++ является байтом в ассемблере, целая в C++ - эквивалентом ассемблерного слова и т.д.
Обратный процесс - передача аргументов из языка ассемблера в C++ - требует иной тактики:
proc _asmfunction C c_arg:byte, k_arg:word
“C” после имени функции указывает, что аргументы приводятся для языка С (т.е. они выталкиваются в стек в порядке справа налево). Остальное также, как и для директивы ARG.
В результате Turbo Assembler автоматически пишет инструкции для сохранения, инициализации и восстановления bp. При использовании этой альтернативной методики не приходится проводить точные операции по выталкиванию bp. За исключением этого отличия, в остальном процесс программирования остается тем же самым.