Skip to content

Commit 332a2fb

Browse files
implement sections, .text, .data, .bss, fixes #4
1 parent 1ba31b8 commit 332a2fb

File tree

4 files changed

+71
-25
lines changed

4 files changed

+71
-25
lines changed

demo.s

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# comment-only line
22

3+
.text
4+
35
start: ld r0, r1, 0 # a comment!
46
st r0, r1, 0
57
add r0, r1, r2
@@ -48,3 +50,7 @@ start: ld r0, r1, 0 # a comment!
4850
halt
4951
end:
5052

53+
.data
54+
55+
.bss
56+

esp32_ulp/__main__.py

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,8 @@ def main(fn):
88
lines = f.readlines()
99

1010
assembler = Assembler()
11-
symbols, code = assembler.assemble(lines)
12-
13-
print('Symbols:')
14-
for name, value in sorted(symbols.items()):
15-
print(name, ':', value)
16-
17-
print('Code:')
18-
for ins in code:
19-
print(hex(ins))
11+
assembler.assemble(lines)
12+
assembler.dump()
2013

2114

2215
main(sys.argv[1])

esp32_ulp/assemble.py

Lines changed: 55 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,15 @@
44

55
from . import opcodes
66

7+
TEXT, DATA, BSS = 'text', 'data', 'bss'
8+
79
class Assembler:
10+
811
def __init__(self):
912
self.symbols = {}
10-
self.code = []
11-
self.addr = 0
13+
self.sections = dict(text=[], data=[], bss=0)
14+
self.offsets = dict(text=0, data=0, bss=0)
15+
self.section = TEXT
1216

1317
def parse_line(self, line):
1418
"""
@@ -48,18 +52,59 @@ def parse(self, lines):
4852
return [p for p in parsed if p is not None]
4953

5054

55+
def append_section(self, value, expected_section=None):
56+
s = self.section
57+
if expected_section is not None and s is not expected_section:
58+
raise TypeError('only allowed in %s section' % expected_section)
59+
if s is TEXT or s is DATA:
60+
self.sections[s].append(value)
61+
self.offsets[s] += 1
62+
elif s is BSS:
63+
self.sections[s] += value # just increase BSS size by value
64+
65+
def dump(self):
66+
print("Symbols:")
67+
for label, section_offset in sorted(self.symbols.items()):
68+
print(label, section_offset)
69+
print("%s section:" % TEXT)
70+
for t in self.sections[TEXT]:
71+
print(hex(t))
72+
print("%s section:" % DATA)
73+
for d in self.sections[DATA]:
74+
print(d)
75+
print("%s section:" % BSS)
76+
print("size: %d" % self.sections[BSS])
77+
78+
def d_text(self):
79+
self.section = TEXT
80+
81+
def d_data(self):
82+
self.section = DATA
83+
84+
def d_bss(self):
85+
self.section = BSS
86+
5187
def assemble(self, lines):
5288
for label, opcode, args in self.parse(lines):
5389
if label is not None:
5490
if label in self.symbols:
5591
raise Exception('label %s is already defined.' % label)
56-
self.symbols[label] = self.addr
92+
self.symbols[label] = (self.section, self.offsets[self.section])
5793
if opcode is not None:
58-
func = getattr(opcodes, 'i_' + opcode, None)
59-
if func is None:
60-
raise Exception('Unknown opcode: %s' % opcode)
61-
instruction = func(*args)
62-
self.code.append(instruction)
63-
self.addr += 1
64-
return self.symbols, self.code
94+
if opcode[0] == '.':
95+
# assembler directive
96+
func = getattr(self, 'd_' + opcode[1:])
97+
if func is not None:
98+
result = func(*args)
99+
if result is not None:
100+
self.append_section(result)
101+
continue
102+
else:
103+
# machine instruction
104+
func = getattr(opcodes, 'i_' + opcode, None)
105+
if func is not None:
106+
instruction = func(*args)
107+
self.append_section(instruction, TEXT)
108+
continue
109+
raise Exception('Unknown opcode or directive: %s' % opcode)
65110

tests/assemble.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from esp32_ulp.assemble import Assembler
1+
from esp32_ulp.assemble import Assembler, TEXT, DATA, BSS
22

33
src = """\
44
# line 1
@@ -38,11 +38,13 @@ def test_parse():
3838
def test_assemble():
3939
a = Assembler()
4040
lines = src.splitlines()
41-
symbols, code = a.assemble(lines)
42-
assert {'start', 'end'} <= set(symbols)
43-
assert symbols['start'] == 0
44-
assert symbols['end'] == 4
45-
assert len(code) == 4
41+
a.assemble(lines)
42+
assert {'start', 'end'} <= set(a.symbols)
43+
assert a.symbols['start'] == (TEXT, 0)
44+
assert a.symbols['end'] == (TEXT, 4)
45+
assert len(a.sections[TEXT]) == 4
46+
assert len(a.sections[DATA]) == 0
47+
assert a.sections[BSS] == 0
4648

4749

4850
test_parse_line()

0 commit comments

Comments
 (0)