-
Notifications
You must be signed in to change notification settings - Fork 1
/
stage3.S
89 lines (71 loc) · 2.37 KB
/
stage3.S
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
/*
* This file is part of smile: ASCII-safe binaries
* Copyright (C) 2011, 2021, [email protected]
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
/*
* Stage3 is basically a radix converter for big numbers
*
* text2binary:
* pool = 0;
* while (*inPtr) {
* if (isAlpha(*inPtr))
* pool = pool * 13 + decodeRadix13(*inPtr++);
* else
* pool = pool * 10 + decodeRadix10(*inPtr++);
*
* if (pool & 0xff00) {
* // pool contains a radix256 number, extract a byte
* *outPtr++ = pool;
* pool >>= 8;
* }
* }
*/
.code16
// load configuration
#include "stage1.inc"
Stage3Start:
// inherit %bp and %di from stage2.
// use %dx as pool, %ax as enum
clr %dx // clear pool
GetEnum:
movzx OFSTEXT(%di),%ax // Read next input character
inc %di // shift input position
dec %bx // increment distance input/output, decrement because %bx is used negatively
subb $'a'-2,%al // test for alpha. Need the extra 2 for the charset decoding
jae GotAlpha // yes, jump higher or same
subb $'0'-'a'+2,%al // test for numeric (and compensate for the previous -2)
jb GetEnum // no, next char
GotNumeric:
imul $10,%dx,%dx // grow pool for radix10
jmp GotEnum
GotAlpha:
imul $13,%dx,%dx // grow pool for radix13
shr %al // divide by 2
jnc GotEnum // jump if input was even
cmp $9,%al // if "vxz"
je GotEnum
sub $7,%al // then shift to fill gap
GotEnum:
addw %ax,%dx // inject
orb %dh,%dh // test if byte present
je GetEnum // no, keep lurking
cmp $STAGE3EOS,%dx // test for end-of-sequence
je Stage4Start // jump if found
movb %dl,OFSHEAD(%bx,%di) // save byte
inc %bx // shift output position
shrw $8,%dx // reduce pool
jmp GetEnum // loop
Stage4Start: