-
ABS и SGN в машкоде
Всем привет.
Покритикуйте мою реализацию функций ABS и SGN для байта и слова, может можно как-то оптимизировать.
Байтовый аргумент поступает в регистре L, результат возвращается в нём же. Слова - в паре HL. Таковы соглашения модели вызова __z88dk_fastcall.
Код:
/*--------------------------------- Cut here ---------------------------------*/
signed char Basic_ABS (signed char x) __z88dk_fastcall {
__asm
BIT 7,L
RET Z
XOR A
SUB L
LD L,A
__endasm;
} //Basic_ABS
/*--------------------------------- Cut here ---------------------------------*/
signed int Basic_ABSI (signed int x) __z88dk_fastcall {
__asm
BIT 7,H
RET Z
EX DE,HL
XOR A
LD L,A
LD H,A
SBC HL,DE
__endasm;
} //Basic_ABSI
/*--------------------------------- Cut here ---------------------------------*/
signed char Basic_SGN (signed char x) __z88dk_fastcall {
__asm
LD A,L
OR L
RET Z
BIT 7,L
LD L,#0xFF
RET NZ
LD L,#1
__endasm;
} //Basic_SGN
/*--------------------------------- Cut here ---------------------------------*/
signed char Basic_SGNI (signed int x) __z88dk_fastcall {
__asm
LD A,H
OR L
RET Z
BIT 7,H
LD L,#0xFF
RET NZ
LD L,#1
__endasm;
} //Basic_SGNI
-
Идеально, оптимизировать нечего ;)
-
Цитата:
Сообщение от
Oleg N. Cher
На такт быстрее.
-
-
-
Код:
bit 7,h ;8
ret z ;5 11
ex de,hl ;4
xor a ;4
ld l,a ;4
ld h,a ;4
sbc hl,de ;15
ret ;10
;19 54 оригинальная процедура
Код:
bit 7,h ;8
ret z ;5 11
ld a,h ;4
cpl ;4
ld h,a ;4
ld a,l ;4
cpl ;4
ld l,a ;4
inc hl ;6
ret ;10
;19 53
Код:
ld a,h ;4
cp $80 ;7 возможно +-$01
ret c ;5 11
cpl ;4
ld h,a ;4
ld a,l ;4
cpl ;4
ld l,a ;4
inc hl ;6
ret ;10
;22 52
- - - Добавлено - - -
Цитата:
Сообщение от Alex Rider
Цитата:
XOR A
LD L,A
LD H,A
LD L,0
LD H,L
На такт быстрее.
LD HL,$0000 в таком случае на 2 такта быстрее;)
-
Не проверял. На вскидку так:
Код:
LD A,H ; 4
OR A ; 4
RET P ; 5 / 11
CPL ; 4
LD H,A ; 4
LD A,L ; 4
CPL ; 4
LD L,A ; 4
INC HL ; 6
RET ; 10
; 19 / 49
Код:
LD A,$FF ; 7
XOR H ; 4
RET M ; 5 / 11
LD H,A ; 4
LD A,L ; 4
CPL ; 4
LD L,A ; 4
INC HL ; 6
RET ; 10
; 22 / 48
-
SGN можно запилить 100500-ю способами
Код:
;оригинальная процедура
LD A,L ;4
OR L ;4
RET Z ;5 11
BIT 7,L ;8
LD L,#0xFF ;7
RET NZ ;5 11
LD L,#1 ;7
RET ;10
;+=50 0=19 -=39
;36 в среднем ; 44,5 в среднем без 0
с ходу придумалось так
Код:
ld a,l ;4
rlca ;4 возможно rla (нужно чтоб флаг С не попадал в А)
jp c,l1 ;10 (7 12 JR)
or a ;4
ret z ;5 11
ld l,$01 ;7
ret ;10
l1
ld l,$FF ;7
ret ;10
;с использованием JP
;+=44 0=33 -=35
;37,3 в среднем ;39,5 в среднем без 0
;с использованием JR
;+=41 0=30 -=37
;36 в среднем ; 39 в среднем без 0
думаю можно и в 600 раз быстрее как минимум
кажется мне оптимизировать процедуру чтоб проверка на 0(1 против 255 других входящих значений) выполнялась быстрей всего нет смысла
правда я хз в какой ситуации применять sgn
- - - Добавлено - - -
Цитата:
вы и правда так кодите
мну *****кодер 80 уровня
Я только сегодня узнал что такое sgn:rolleyes:
глядя на код в самом верху:D
кто мне не дает так кодить?
- - - Добавлено - - -
MOAR SPEED!!!
Код:
rlc l ;8
ret z ;5 11
jp c,l1 ;10 (7 12 JR)
ld l,$01 ;7
ret ;10
l1
ld l,$FF ;7
ret ;10
;с использованием JP
;+=40 0=19 -=40
;33 в среднем ;40 в среднем без 0
;с использованием JR
;+=37 0=19 -=42
;32,6 в среднем ;39,5 в среднем без 0
АND MOAR!!!!
Код:
rlc l ;8
ret z ;5 11
ld l,$01 ;7 ;ld l,$FF
ret nc ;5 11 ;ret c
ld l,$FF ;7 ;ld l,$01
ret ;10
;-=31 0=19 +=42
;30,6 в среднем ;36,5 в среднем без 0
;легко реверсится в
;-=42 0=19 +=31 (если положительные числа встречаются чаще(а они наверное встречаются чаще))
- - - Добавлено - - -
Код:
;оригинальная процедура
BIT 7,L 8
RET Z 5 11
XOR A 4
SUB L 4
LD L,A 4
RET 10
;19 35
Код:
xor a ;4
sub l ;4
ret m ;5 11
ld l,a ;4
ret ;10
;19 27
;по ходу дает ложный результат при $00 и $80 перепроверьте кто нить!!!
-
А какой результат должно дать ABS($80)? Разве не $80? Просто у него нет симметричного положительного :-)
- - - Добавлено - - -
Код:
/*--------------------------------- Cut here ---------------------------------*/
signed char Basic_SGN (signed char x) __z88dk_fastcall { // Code by NEO SPECTRUMAN
__asm
RLC L ; 8
RET Z ; 5 11
LD L,#1 ; 7
RET NC ; 5 11
LD L,#0xFF ; 7
__endasm;
} //Basic_SGN
NEO SPECTRUMAN, зачётный код, респект! Я бы так не додумался. :-) Вот что значит опыт низкоуровневого кодинга. У меня он небольшой. Интересно, как бы Вы оптимизировали Laser2 :-)
-
;sgn
rlc l
ret z
sbc a,a
ld l,a
set 0,l
+
jr nc, -> 0..127
jr c, -> -128..-1