Вызов программы ASM из Си » History » Version 6
krufter_multiclet, 07/19/2013 06:04 PM
1 | 1 | krufter_multiclet | h1. Вызов программы ASM из Си |
---|---|---|---|
2 | 1 | krufter_multiclet | |
3 | 1 | krufter_multiclet | Вызов программы, написанной на ассемблере из Си организован при помощи стека. Подробнее о стеке можно прочитать тут [[Обзор работы со стеком]]. |
4 | 2 | krufter_multiclet | |
5 | 2 | krufter_multiclet | Рассмотрим пример вызова процедуры, написанной на ассемблере, из Си функцией типа *void*. |
6 | 2 | krufter_multiclet | |
7 | 2 | krufter_multiclet | Пусть программа на ассемблере принимает два аргумента и выполняет их сложение, а также выдает результат через UART. |
8 | 2 | krufter_multiclet | |
9 | 2 | krufter_multiclet | На Си вызов функции будет выглядеть так: |
10 | 2 | krufter_multiclet | |
11 | 2 | krufter_multiclet | <pre> |
12 | 2 | krufter_multiclet | #include <HDL51001_ccf.h> |
13 | 2 | krufter_multiclet | |
14 | 2 | krufter_multiclet | void function_add(int arg1, int arg2); |
15 | 2 | krufter_multiclet | |
16 | 2 | krufter_multiclet | void main() |
17 | 2 | krufter_multiclet | { |
18 | 2 | krufter_multiclet | int a,b; |
19 | 2 | krufter_multiclet | |
20 | 2 | krufter_multiclet | a = 19; |
21 | 2 | krufter_multiclet | b = 7; |
22 | 2 | krufter_multiclet | function_add(a,b); |
23 | 2 | krufter_multiclet | a = 20; |
24 | 2 | krufter_multiclet | b = 13; |
25 | 2 | krufter_multiclet | function_add(a,b); |
26 | 2 | krufter_multiclet | } |
27 | 2 | krufter_multiclet | |
28 | 2 | krufter_multiclet | </pre> |
29 | 3 | krufter_multiclet | |
30 | 3 | krufter_multiclet | На ассемблере будет следующее: |
31 | 3 | krufter_multiclet | |
32 | 3 | krufter_multiclet | <pre> |
33 | 4 | krufter_multiclet | .alias ron2 4 ; в реальной программе мы должны сохранить текущие значения РОНов в стеке и только потом их использовать и |
34 | 4 | krufter_multiclet | .alias ron3 5 ; перед возвратом в Си восстановить их первоначальные значения, но для простоты примера мы это не сделаем. |
35 | 3 | krufter_multiclet | |
36 | 5 | krufter_multiclet | ;настриваем UART для платы HW1-MCp04 |
37 | 3 | krufter_multiclet | .alias UART_DATA UART0_DATA |
38 | 3 | krufter_multiclet | .alias UART_BDR UART0_BDR |
39 | 3 | krufter_multiclet | .alias UART_ST UART0_ST |
40 | 3 | krufter_multiclet | .alias UART_CR UART0_CR |
41 | 3 | krufter_multiclet | |
42 | 3 | krufter_multiclet | .alias UART_PORT_PIN 0x300 |
43 | 3 | krufter_multiclet | .alias UART_PORT_BPS GPIOB_BPS |
44 | 3 | krufter_multiclet | |
45 | 3 | krufter_multiclet | .global function_ex |
46 | 3 | krufter_multiclet | |
47 | 3 | krufter_multiclet | .text |
48 | 3 | krufter_multiclet | |
49 | 3 | krufter_multiclet | function_ex: |
50 | 3 | krufter_multiclet | rdl #SP, 4 ;получаем первый аргумент |
51 | 3 | krufter_multiclet | rdl #SP, 8 ;получаем второй аргумент |
52 | 3 | krufter_multiclet | addl @1, @2 ;складываем аргументы |
53 | 3 | krufter_multiclet | setl #ron3, @1 |
54 | 3 | krufter_multiclet | jmp initUART |
55 | 3 | krufter_multiclet | complete |
56 | 3 | krufter_multiclet | |
57 | 3 | krufter_multiclet | initUART: |
58 | 3 | krufter_multiclet | getl 0x00000300 |
59 | 3 | krufter_multiclet | wrl @1, UART_PORT_BPS |
60 | 3 | krufter_multiclet | getl 0x00000104 |
61 | 3 | krufter_multiclet | wrl @1, UART_BDR |
62 | 3 | krufter_multiclet | getl 0x00000003 |
63 | 3 | krufter_multiclet | wrl @1, UART_CR |
64 | 3 | krufter_multiclet | jmp send_byte_UART |
65 | 3 | krufter_multiclet | setl #ron2, 7 |
66 | 3 | krufter_multiclet | complete |
67 | 3 | krufter_multiclet | |
68 | 3 | krufter_multiclet | send_byte_UART: |
69 | 3 | krufter_multiclet | getl #ron2 |
70 | 3 | krufter_multiclet | jne @1, send_byte_UART |
71 | 3 | krufter_multiclet | je @2, buf_TXD |
72 | 3 | krufter_multiclet | getq #ron3 |
73 | 3 | krufter_multiclet | slrq @1, 8 |
74 | 3 | krufter_multiclet | setq #ron3, @1 |
75 | 3 | krufter_multiclet | wrl @3, UART_DATA |
76 | 3 | krufter_multiclet | subl @7, 1 |
77 | 3 | krufter_multiclet | setl #ron2, @1 |
78 | 3 | krufter_multiclet | complete |
79 | 3 | krufter_multiclet | |
80 | 3 | krufter_multiclet | buf_TXD: |
81 | 3 | krufter_multiclet | rdl UART_ST |
82 | 3 | krufter_multiclet | getl 0x00000004 |
83 | 3 | krufter_multiclet | and @1, @2 |
84 | 3 | krufter_multiclet | je @1, buf_TXD |
85 | 3 | krufter_multiclet | jne @2, return |
86 | 3 | krufter_multiclet | complete |
87 | 3 | krufter_multiclet | |
88 | 3 | krufter_multiclet | return: |
89 | 3 | krufter_multiclet | rdl #SP |
90 | 3 | krufter_multiclet | jmp @1 |
91 | 3 | krufter_multiclet | complete |
92 | 3 | krufter_multiclet | |
93 | 3 | krufter_multiclet | </pre> |
94 | 6 | krufter_multiclet | |
95 | 6 | krufter_multiclet | Параграфы function_ex и return составляют всю работы со стеком, т.е. работа со стеком заняла 3 строчки. |