Вызов программы ASM из Си » History » Version 8
Version 7 (krufter_multiclet, 07/19/2013 06:05 PM) → Version 8/20 (krufter_multiclet, 07/19/2013 06:05 PM)
h1. Вызов программы ASM из Си
Вызов программы, написанной на ассемблере из Си организован при помощи стека. Подробнее о стеке можно прочитать тут [[Обзор работы со стеком]].
Рассмотрим пример вызова процедуры, написанной на ассемблере, из Си функцией типа *void*.
Пусть программа на ассемблере принимает два аргумента и выполняет их сложение, а также выдает результат через UART.
На Си вызов функции будет выглядеть так:
<pre>
#include <HDL51001_ccf.h>
void function_add(int arg1, int arg2);
void main()
{
int a,b;
a = 19;
b = 7;
function_add(a,b);
a = 20;
b = 13;
function_add(a,b);
}
</pre>
На ассемблере будет следующее:
<pre>
.alias ron2 4 ; в реальной программе мы должны сохранить текущие значения РОНов в стеке и только потом их использовать и
.alias ron3 5 ; перед возвратом в Си восстановить их первоначальные значения, но для простоты примера мы это не сделаем.
;настриваем UART для платы HW1-MCp04
.alias UART_DATA UART0_DATA
.alias UART_BDR UART0_BDR
.alias UART_ST UART0_ST
.alias UART_CR UART0_CR
.alias UART_PORT_PIN 0x300
.alias UART_PORT_BPS GPIOB_BPS
.global function_ex
.text
function_ex:
rdl #SP, 4 ;получаем первый аргумент
rdl #SP, 8 ;получаем второй аргумент
addl @1, @2 ;складываем аргументы
setl #ron3, @1
jmp initUART
complete
initUART:
getl 0x00000300
wrl @1, UART_PORT_BPS
getl 0x00000104
wrl @1, UART_BDR
getl 0x00000003
wrl @1, UART_CR
jmp send_byte_UART
setl #ron2, 7
complete
send_byte_UART:
getl #ron2
jne @1, send_byte_UART
je @2, buf_TXD
getq #ron3
slrq @1, 8
setq #ron3, @1
wrl @3, UART_DATA
subl @7, 1
setl #ron2, @1
complete
buf_TXD:
rdl UART_ST
getl 0x00000004
and @1, @2
je @1, buf_TXD
jne @2, return
complete
return:
rdl #SP
jmp @1
complete
</pre>
Параграфы function_ex и return составляют всю работы со стеком, т.е. работа со стеком заняла 4 3 команды.
Вызов программы, написанной на ассемблере из Си организован при помощи стека. Подробнее о стеке можно прочитать тут [[Обзор работы со стеком]].
Рассмотрим пример вызова процедуры, написанной на ассемблере, из Си функцией типа *void*.
Пусть программа на ассемблере принимает два аргумента и выполняет их сложение, а также выдает результат через UART.
На Си вызов функции будет выглядеть так:
<pre>
#include <HDL51001_ccf.h>
void function_add(int arg1, int arg2);
void main()
{
int a,b;
a = 19;
b = 7;
function_add(a,b);
a = 20;
b = 13;
function_add(a,b);
}
</pre>
На ассемблере будет следующее:
<pre>
.alias ron2 4 ; в реальной программе мы должны сохранить текущие значения РОНов в стеке и только потом их использовать и
.alias ron3 5 ; перед возвратом в Си восстановить их первоначальные значения, но для простоты примера мы это не сделаем.
;настриваем UART для платы HW1-MCp04
.alias UART_DATA UART0_DATA
.alias UART_BDR UART0_BDR
.alias UART_ST UART0_ST
.alias UART_CR UART0_CR
.alias UART_PORT_PIN 0x300
.alias UART_PORT_BPS GPIOB_BPS
.global function_ex
.text
function_ex:
rdl #SP, 4 ;получаем первый аргумент
rdl #SP, 8 ;получаем второй аргумент
addl @1, @2 ;складываем аргументы
setl #ron3, @1
jmp initUART
complete
initUART:
getl 0x00000300
wrl @1, UART_PORT_BPS
getl 0x00000104
wrl @1, UART_BDR
getl 0x00000003
wrl @1, UART_CR
jmp send_byte_UART
setl #ron2, 7
complete
send_byte_UART:
getl #ron2
jne @1, send_byte_UART
je @2, buf_TXD
getq #ron3
slrq @1, 8
setq #ron3, @1
wrl @3, UART_DATA
subl @7, 1
setl #ron2, @1
complete
buf_TXD:
rdl UART_ST
getl 0x00000004
and @1, @2
je @1, buf_TXD
jne @2, return
complete
return:
rdl #SP
jmp @1
complete
</pre>
Параграфы function_ex и return составляют всю работы со стеком, т.е. работа со стеком заняла 4 3 команды.