[an error occurred while processing this directive]
[an error occurred while processing this directive]
|
IMHO лучше всю функцию сразу писать на асме, чем вставлять кусок в C.
Только для того, чтобы задействовать global register optimisation
надо указать измененные регистры (из списка a, B, C, R0-R7,
DPH, DPL) при помощи директивы $RU. Иначе компилятор потом считает,
что данная функция портит все регистры.
Я обзавелся макросами
ENTRY MACRO fname,used ; used - список испорченных регистров,
public fname ; пустые круглые скобки, если ни один регистр
if not nul used ; не портится
$RU fname used
endif
ENDM
В основном используется FUNC: FUNC _imemcmp,<(a,C,R0,R1,R3,R7)> макрос ENTRY использую в основном тогда, когда хочу получить две точки ?PR?IMEMSET segment CODE
E-mail:
info@telesys.ru
FUNC MACRO fname,used,attr
?PR?&fname SEGMENT CODE attr ; объявляется сегмент с именем по соглашениям
RSEG ?PR?&fname ; для построения дерева вызовов
ENTRY fname,
ENDM
_imemcmp: ;;;;;;;;;;;;;;;;;;;
; i8 imemcmp( void idata *dst, void idata *src, u8 bytes);
mov R0,AR7 ; dst
mov R1,AR5 ; src
L?a:
mov a,@R0
sub a,@R1
jnz L?b
inc R0
inc R1
djnz R3,L?a
mov R7,#0
ret
L?b:
mov R7,#1
jnc L?c
mov R7,#0xFF
L?c:
ret
входа в одну функцию или поместить несколько функций в один сегмент
(например, если они вызывают друг друга или вспомогательные через
acall - тогда их все надо в один сегмент, да еще и с аттрибутом INBLOCK)
RSEG ?PR?IMEMSET
ENTRY _imemzero, <(R0,R3,R5)>
ENTRY _imemfill, <(R0,R5)>
_imemzero: ;;;;;;;;;;;;;;;;;;;
;void imemzero( void idata *dst, u8 len);
mov R3,#0
_imemfill: ;;;;;;;;;;;;;;;;;;;
;void imemfill( void idata *dst, u8 len, u8 val);
mov R0,AR7
L?L:
mov @R0,AR3
inc R0
djnz R5,L?L
ret
Ответы