Дизассемблер Yozh

Советский компьютер Радио-86РК (1986) и его клоны

Moderator: Shaos

User avatar
Shaos
Admin
Posts: 24067
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Re: Дизассемблер Yozh

Post by Shaos »

vital72 wrote:покодил пару часов и получилось нописать дизассм в 1231 байт. мне интересно глянуть на код дизассма в 1 килобайт
...
говнокодил не долго, на все инструкции не тестировал.
использует внутренние вызовы Монитора, но это не должно быть проблемой, т.к. для Монитора и писалось.
использует внутренний буфер Монитора для ввода стоки.
сейчас нет обработки Ctrl+C, но проблем добавить быть не должно, код как раз писался как шаблон.
логика полностью скопирована из моего же дизассма на JS.
если что-то не компилируется: я использую немного модифицированный компилятор с сайта https://www.asm80.com/, пока свой компилер не написал, приходится использовать чужое.
О - круто, спасибо! :)

P.S. Спрятал простыню под спойлер
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
vital72
Senior
Posts: 181
Joined: 17 Jun 2014 04:29
Location: 93.80.157.217

Re: Дизассемблер Yozh

Post by vital72 »

да, зобыл нописать.
вход: HL -- адрес начала блока
DE -- адрес конец блока
вызов по метке disassm
ну это по коду вроде понятно, вобщем, как параметры в Мониторе по регистрам раскладываются, так и тут.
https://radio-86rk.ru
кто я такой, чтобы спорить с самим собой
User avatar
Shaos
Admin
Posts: 24067
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Re: Дизассемблер Yozh

Post by Shaos »

Да, хитро' написано :egeek:

Можно попробовать 135 байт сэкономить, храня слова по 5 бит на букву - это 4 символа в 20 битах (т.е. не кратно байту) вместо теперешних 32. А можно ещё и статистически подойти к вопросу поглядев на распределение вероятностей:

Code: Select all

0)      . [32] =        88
1)      A [65] =        21
2)      B [66] =        5
3)      C [67] =        29
4)      D [68] =        18
5)      E [69] =        6
6)      G [71] =        1
7)      H [72] =        12
8)      I [73] =        19
9)      J [74] =        11
10)     K [75] =        2
11)     L [76] =        21
12)     M [77] =        11
13)     N [78] =        13
14)     O [79] =        9
15)     P [80] =        18
16)     R [82] =        26
17)     S [83] =        16
18)     T [84] =        9
19)     U [85] =        5
20)     V [86] =        3
21)     X [88] =        11
22)     Z [90] =        6
Как можно видеть реально используются только 22 латинские буквы вместо 26 (плюс пробел) - если тупо математически, то это 22^4=234256, что умещается в 18 битах - уже экономия 157 байт (хотя тот факт, что оно не кратно байту добавит лишнего кода), а если ещё и отсортировать по частоте:

Code: Select all

0)      . [32] =        88
3)      C [67] =        29
16)     R [82] =        26
1)      A [65] =        21
11)     L [76] =        21
8)      I [73] =        19
4)      D [68] =        18
15)     P [80] =        18
17)     S [83] =        16
13)     N [78] =        13
7)      H [72] =        12
9)      J [74] =        11
21)     X [88] =        11
12)     M [77] =        11
18)     T [84] =        9
14)     O [79] =        9
5)      E [69] =        6
22)     Z [90] =        6
2)      B [66] =        5
19)     U [85] =        5
20)     V [86] =        3
10)     K [75] =        2
6)      G [71] =        1
то можно типа какого-то микрохаффмана организовать пользуясь этой информацией:

Code: Select all

Space,10
C,1110
R,1101
L,0101
A,0100
I,0011
P,0001
D,0000
S,11111
N,11001
H,11000
M,01110
X,01101
J,01100
O,00100
T,111101
Z,111100
E,011111
U,001011
B,001010
V,0111101
K,01111001
G,01111000
что даст:

Code: Select all

MOV 	-> 19 bits
MVI 	-> 18 bits
STAX	-> 20 bits
LDAX	-> 17 bits
STA 	-> 17 bits
LDA 	-> 14 bits
LXI 	-> 15 bits
SHLD	-> 18 bits
LHLD	-> 17 bits
PUSH	-> 20 bits
POP 	-> 15 bits
SPHL	-> 18 bits
XCHG	-> 22 bits
XTHL	-> 20 bits
IN 	-> 11 bits
OUT 	-> 19 bits
CMC 	-> 15 bits
STC 	-> 17 bits
CMA 	-> 15 bits
DAA 	-> 14 bits
INR 	-> 15 bits
DCR 	-> 14 bits
INX 	-> 16 bits
DCX 	-> 15 bits
ADD 	-> 14 bits
ADC 	-> 14 bits
SUB 	-> 19 bits
SBB 	-> 19 bits
ANA 	-> 15 bits
ORA 	-> 15 bits
XRA 	-> 15 bits
CMP 	-> 15 bits
ADI 	-> 14 bits
ACI 	-> 14 bits
SUI 	-> 17 bits
SBI 	-> 17 bits
ANI 	-> 15 bits
ORI 	-> 15 bits
XRI 	-> 15 bits
CPI 	-> 14 bits
DAD 	-> 14 bits
RLC 	-> 14 bits
RAL 	-> 14 bits
RRC 	-> 14 bits
RAR 	-> 14 bits
PCHL	-> 17 bits
JMP 	-> 16 bits
CALL	-> 16 bits
RST 	-> 17 bits
RET 	-> 18 bits
JNZ 	-> 18 bits
JZ 	-> 13 bits
JNC 	-> 16 bits
JC 	-> 11 bits
JPO 	-> 16 bits
JPE 	-> 17 bits
JP 	-> 11 bits
JM 	-> 12 bits
CNZ 	-> 17 bits
CZ 	-> 12 bits
CNC 	-> 15 bits
CC 	-> 10 bits
CPO 	-> 15 bits
CPE 	-> 16 bits
CP 	-> 10 bits
CM 	-> 11 bits
RNZ 	-> 17 bits
RZ 	-> 12 bits
RNC 	-> 15 bits
RC 	-> 10 bits
RPO 	-> 15 bits
RPE 	-> 16 bits
RP 	-> 10 bits
RM 	-> 11 bits
EI 	-> 12 bits
DI 	-> 10 bits
HLT 	-> 17 bits
NOP 	-> 16 bits
DSUB	-> 21 bits
ARHL	-> 17 bits
RLDE	-> 18 bits
RIM 	-> 15 bits
SIM 	-> 16 bits
LDHI	-> 17 bits
LDSI	-> 17 bits
RSTV	-> 22 bits
SHLX	-> 19 bits
LHLX	-> 18 bits
JNK 	-> 20 bits
JK 	-> 15 bits
однако из-за того, что нам надо одинаковое смещение между словами, то придётся брать максимум из получившегося, а это 22 бита - округляем до 24, что есть 3 байта на слово или 270 байт на весь словарь, что даёт выгоду только в 90 байт по сравнению с первоначальным вариантом. Можно комбинированный вариант сделать - быстро получаем доступ к коротким словам и чуть более долгий для длинных - скажем 20 бит и меньше храним вместе и 21-22 - храним отдельно. Выходит, что отдельно идут только:

Code: Select all

XCHG	-> 22 bits
DSUB	-> 21 bits
RSTV	-> 22 bits
и этот вариант всё равно получается хуже, чем первый, значит нафиг микрохаффмана - проще всего пойти по 5-битному пути на букву (первый вариант). Однако если наплевать на быстродействие и просто расположить все мнемоники битовой цепочкой, то с использованием микрохаффмана они займут всего 179 байт т.е. экономя 181 байт - почти в 2 раза меньше! Однако ещё надо прикинуть сколько будет весить код, раскодирующий эти мнемоники деревом...

P.S. Можно двух и трёх-буквенные мнемоники сделать "быстрыми", а четырёхбуквенные (18 штук) - медленными:

Code: Select all

ARHL
CALL
DSUB
LDAX
LDHI
LDSI
LHLD
LHLX
PCHL
PUSH
RLDE
RSTV
SHLD
SHLX
SPHL
STAX
XCHG
XTHL
в таком случае таблица быстрых мнемоник будет храниться в 3*5=15 битах на слово и 16-й бит будет означать, что нужно откуда-то вычитать четвёртую букву, т.е. это будет 90*2=180 байт плюс логика "дописывания" четвёртой буквы (надо прикинуть сколько байт она может занять и стоит ли оно вообще того). Четвёртых букв у нас только 9:

Code: Select all

      5 L
      4 X
      2 I
      2 D
      1 V
      1 H
      1 G
      1 E
      1 B
и ещё у 8085-х инструкций надо пометочку поставить, что они не родные...

P.P.S. Сложноватая логика потребуется, чтобы четвёртую букву программно дописывать:

Code: Select all

STAX 02,12
LDAX 0A,1A
SHLD 22
LHLD 2A
PUSH C5,D5,E5,F5
SPHL F9
XCHG EB
XTHL E3
PCHL E9
CALL CD
DSUB 08 *
ARHL 10 *
RLDE 18 *
LDHI 28 *
LDSI 38 *
RSTV CB *
SHLX D9 *
LHLX ED *

4th letter:
      L -> F9,E3,E9,CD,10
      X -> 02,12,0A,1A,D9,ED
      I -> 28,38
      D -> 22,2A
      V -> CB
      H -> C5,D5,E5,F5
      G -> EB
      E -> 18
      B -> 08
я там звёздочки поставил у четырёхбуквенных инструкций от 8085, а вот остальные:

Code: Select all

RIM  20 *
SIM  30 *
JNK  DD *
JK   FD *
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 24067
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Re: Дизассемблер Yozh

Post by Shaos »

Обработал исходник напильником (выкинув макрос), чтобы собиралось с помощью vinxru-шного pdp11asm (2017) - сейчас убедюсь, что работает и выложу... вроде работает :mrgreen:
Screenshot from 2024-02-07 22-43-28.png
Вот эту функцию ещё упростил, а то pdp11asm не понимает high/low - было:

Code: Select all

disassm_get_reg8:
   push   h
   adi   low (disassm_reg8_8085)
   mov   l, a
   mvi   a, 0
   aci   high (disassm_reg8_8085)
   mov   h, a
   mov   a, m
   pop   h
   ret
стало:

Code: Select all

disassm_get_reg8:
	push	h
	push	b
	lxi	h, disassm_reg8_8085
	mov	c, a
	mvi	b, 0
	dad	b
	mov	a, m
	pop	b
	pop	h
	ret
You do not have the required permissions to view the files attached to this post.
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
vital72
Senior
Posts: 181
Joined: 17 Jun 2014 04:29
Location: 93.80.157.217

Re: Дизассемблер Yozh

Post by vital72 »

подумалось.
если в таблице disassm_table_8085 вместо индекса мнемоники всунуть саму мнемонику, то можно сократить розмер примерно на 80 байт
update
тьфу ты
не можно сократить. исчо не проснулсо
https://radio-86rk.ru
кто я такой, чтобы спорить с самим собой
User avatar
Shaos
Admin
Posts: 24067
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Re: Дизассемблер Yozh

Post by Shaos »

саму мнемонику всмысле слово? по идее мой бредовый вариант туда можно попробовать воткнуть где в 2 байта уталкивается 3 буквы и битик говорящий, что есть четвёртая буква (которая добивается программно)

P.S. pdp11asm вот так умеет:

Code: Select all

04D6                      		CHBASE		EQU	'A'
04D6 CC 55                			dw	(('M'-CHBASE)+(('O'-CHBASE)*32)+(('V'-CHBASE)*1024))
тут я слово MOV утолкал в 2 байта и +32768 ещё надо сделать для четырёхбуквенных слов
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
vital72
Senior
Posts: 181
Joined: 17 Jun 2014 04:29
Location: 93.80.157.217

Re: Дизассемблер Yozh

Post by vital72 »

Shaos wrote: Вот эту функцию ещё упростил
high/low можно заменить на это:

Code: Select all

	adi	disassm_reg8_8085 & 0FFh
...
	aci	disassm_reg8_8085 >> 8
или аналогичные операторы, которые есть в асме
https://radio-86rk.ru
кто я такой, чтобы спорить с самим собой
User avatar
Shaos
Admin
Posts: 24067
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Re: Дизассемблер Yozh

Post by Shaos »

не - pdp11asm так не умеет :no:
/256 умеет, а >>8 или &255 - нет
надо чтоли будет добавить это в мой форк, который pdp11asm85...

P.S. Добавил 9 февраля 2024 года :mrgreen:
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
vital72
Senior
Posts: 181
Joined: 17 Jun 2014 04:29
Location: 93.80.157.217

Re: Дизассемблер Yozh

Post by vital72 »

добавление одно байта на строчку в таблицу disassm_table_8085 вздует эту таблицу на 256 байт, в то время как все мнемоники занимают 360 байт
https://radio-86rk.ru
кто я такой, чтобы спорить с самим собой
User avatar
Shaos
Admin
Posts: 24067
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Re: Дизассемблер Yozh

Post by Shaos »

ну т.е. есть экономия? 360-256=104
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
vital72
Senior
Posts: 181
Joined: 17 Jun 2014 04:29
Location: 93.80.157.217

Re: Дизассемблер Yozh

Post by vital72 »

это без учёта кода, который будет всё это обрабатывать.. как бы он не вышел больше
https://radio-86rk.ru
кто я такой, чтобы спорить с самим собой
User avatar
Shaos
Admin
Posts: 24067
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Re: Дизассемблер Yozh

Post by Shaos »

да, тяжеловатый код получается

тогда можно оставить табличку мнемоник отдельно, но сохранять одну букву в 5 бит тогда 4 буквы займут 20 бит - с округлением до 24 бит это будет 3 байта - выгода в 90 байт плюс есть 4 бита на каждое слово куда можно дополнительные флаги положить (типа метка инструкции для 8085 и что-то для Human Readable объяснялок)

P.S. человеческие объяснялки, которые хотелось бы добавить как комментарий:
1) MVI r,n ; r = n ; char
2) MOV r1,r2 ; r1 = r2
3) LXI rr,w ; rr = w
4) STA w ; [w] = A
5) LDA w ; A = [w]
6) STAX rr ; [rr] = A
7) LDAX rr ; A = [rr]
8) SHLD w ; [w] = L ; [w+1] = H
9) LHLD w ; L = [w] ; H = [w+1]
10) SPHL ; SP = HL
11) XCHG ; DE <-> HL
12) XTHL ; HL <-> [SP]
13) PCHL ; PC = HL
14) INR r ; r = r + 1
15) DCR r ; r = r - 1
16) INX rr ; rr = rr + 1
17) DCX rr ; rr = rr - 1
18) CMC ; INVERT FC
19) STC ; SET FC
20) CMA ; A = ~A
21) ADD r ; A = A + r
22) ADI n ; A = A + n ; char
23) ADC r ; A = A + r + FC
24) ACI n ; A = A + n + FC ; char
25) SUB r ; A = A - r
26) SUI n ; A = A - n ; char
27) SBB r ; A = A - r - FC
28) SBI n ; A = A - n - FC ; char
29) ANA r ; A = A AND r
30) ANI n ; A = A AND binary
31) ORA r ; A = A OR r
32) ORI n ; A = A OR binary
33) XRA r ; A = A XOR r
34) XRI n ; A = A XOR binary
35) CPI n ; A == n ; char
36) CMP r ; A == r
37) RLC ; A LEFT CIRC
38) RAL ; A LEFT FC
39) RRC ; A RIGHT CIRC
40) RAR ; A RIGHT FC
41) RST n ; CALL n*8
42) xxxx ; 8085
43) нет объяснялки
чото много получается...

P.P.S. Возможно надо исключить те инструкции, которые единичные (типа CMC или RLC) - по ним тип объяснялки будет "смотри по коду" - тогда укладываемся в 5 бит:

0) нет объяснялки (в этом случае даже ; не печатается)
1) "смотри по коду" (см. список таких инструкций ниже по тексту)
2) xxxx ; 8085 (специфичная для 8085 проца инструкция НЕ объясняется, а просто обозначается как чужеродная)
3) MOV r1,r2 ; r1 = r2
4) LXI rr,w ; rr = w
5) STA w ; [w] = A
6) LDA w ; A = [w]
7) STAX rr ; [rr] = A
8) LDAX rr ; A = [rr]
9) SHLD w ; [w] = L ; [w+1] = H
10) LHLD w ; L = [w] ; H = [w+1]
11) INR r ; r = r + 1
12) DCR r ; r = r - 1
13) INX rr ; rr = rr + 1
14) DCX rr ; rr = rr - 1
15) CMP r ; A == r
16) CPI n ; A == n ; char
17) MVI r,n ; r = n ; char
18) ADD r ; A = A + r
19) ADI n ; A = A + n ; char
20) ADC r ; A = A + r + FC
21) ACI n ; A = A + n + FC ; char
22) SUB r ; A = A - r
23) SUI n ; A = A - n ; char
24) SBB r ; A = A - r - FC
25) SBI n ; A = A - n - FC ; char
26) ANA r ; A = A AND r
27) ANI n ; A = A AND binary
28) ORA r ; A = A OR r
29) ORI n ; A = A OR binary
30) XRA r ; A = A XOR r
31) XRI n ; A = A XOR binary

(как можно видеть в первой половине таблицы есть только варианты со словами, регистрами и регистровыми парами, а во второй - с регистрами, с байтами выводимыми как символы либо выводимыми в бинарном виде)

Варианты для "смотри по коду" только статические:
- SPHL ; SP = HL
- XCHG ; DE <-> HL
- XTHL ; HL <-> [SP]
- PCHL ; PC = HL
- CMC ; INVERT FC
- STC ; SET FC
- CMA ; A = ~A
- RLC ; A LEFT CIRC
- RAL ; A LEFT FC
- RRC ; A RIGHT CIRC
- RAR ; A RIGHT FC
- RST 0 ; CALL #0000
- RST 1 ; CALL #0008
- RST 2 ; CALL #0010
- RST 3 ; CALL #0018
- RST 4 ; CALL #0020
- RST 5 ; CALL #0028
- RST 6 ; CALL #0030
- RST 7 ; CALL #0038
Я тут за главного - если что шлите мыло на me собака shaos точка net
b2m
Devil
Posts: 907
Joined: 26 May 2003 06:57

Re: Дизассемблер Yozh

Post by b2m »

Заменить одну жирную таблицу 512 байт на две 256+89 (т.е. вынести атрибуты команды в отдельную таблицу). Экономия примерно 160 байт.
Страничка эмулятора наших компьютеров
http://bashkiria-2m.narod.ru/
b2m
Devil
Posts: 907
Joined: 26 May 2003 06:57

Re: Дизассемблер Yozh

Post by b2m »

Shaos wrote:Можно попробовать 135 байт сэкономить, храня слова по 5 бит на букву
Усложнится код. Достаточно использовать для конца строки старший бит последнего символа (вместо пробела), уже 89 байт сэкономим.
Страничка эмулятора наших компьютеров
http://bashkiria-2m.narod.ru/
b2m
Devil
Posts: 907
Joined: 26 May 2003 06:57

Re: Дизассемблер Yozh

Post by b2m »

Условия NZ,Z,NC,... тоже можно как параметр команды сделать, уменьшится количество опкодов на 21. С учётом всех таблиц примерно 180 байт. Кода добавится немного.
Страничка эмулятора наших компьютеров
http://bashkiria-2m.narod.ru/