costan-tem_ruby 0.10.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +45 -0
- data/LICENSE +21 -0
- data/Manifest +75 -0
- data/README +8 -0
- data/Rakefile +23 -0
- data/bin/tem_bench +9 -0
- data/bin/tem_ca +13 -0
- data/bin/tem_irb +11 -0
- data/bin/tem_proxy +65 -0
- data/bin/tem_stat +35 -0
- data/dev_ca/ca_cert.cer +0 -0
- data/dev_ca/ca_cert.pem +32 -0
- data/dev_ca/ca_key.pem +27 -0
- data/dev_ca/config.yml +14 -0
- data/lib/tem/_cert.rb +158 -0
- data/lib/tem/apdus/buffers.rb +89 -0
- data/lib/tem/apdus/keys.rb +64 -0
- data/lib/tem/apdus/lifecycle.rb +13 -0
- data/lib/tem/apdus/tag.rb +38 -0
- data/lib/tem/auto_conf.rb +25 -0
- data/lib/tem/builders/abi.rb +482 -0
- data/lib/tem/builders/assembler.rb +314 -0
- data/lib/tem/builders/crypto.rb +124 -0
- data/lib/tem/builders/isa.rb +120 -0
- data/lib/tem/ca.rb +114 -0
- data/lib/tem/definitions/abi.rb +65 -0
- data/lib/tem/definitions/assembler.rb +23 -0
- data/lib/tem/definitions/isa.rb +188 -0
- data/lib/tem/ecert.rb +77 -0
- data/lib/tem/hive.rb +18 -0
- data/lib/tem/keys/asymmetric.rb +116 -0
- data/lib/tem/keys/key.rb +48 -0
- data/lib/tem/keys/symmetric.rb +47 -0
- data/lib/tem/sec_exec_error.rb +63 -0
- data/lib/tem/seclosures.rb +81 -0
- data/lib/tem/secpack.rb +107 -0
- data/lib/tem/tem.rb +31 -0
- data/lib/tem/toolkit.rb +101 -0
- data/lib/tem/transport/auto_configurator.rb +87 -0
- data/lib/tem/transport/java_card_mixin.rb +99 -0
- data/lib/tem/transport/jcop_remote_protocol.rb +59 -0
- data/lib/tem/transport/jcop_remote_server.rb +171 -0
- data/lib/tem/transport/jcop_remote_transport.rb +65 -0
- data/lib/tem/transport/pcsc_transport.rb +87 -0
- data/lib/tem/transport/transport.rb +10 -0
- data/lib/tem_ruby.rb +47 -0
- data/tem_ruby.gemspec +35 -0
- data/test/_test_cert.rb +70 -0
- data/test/builders/test_abi_builder.rb +298 -0
- data/test/tem_test_case.rb +26 -0
- data/test/tem_unit/test_tem_alu.rb +33 -0
- data/test/tem_unit/test_tem_bound_secpack.rb +51 -0
- data/test/tem_unit/test_tem_branching.rb +56 -0
- data/test/tem_unit/test_tem_crypto_asymmetric.rb +123 -0
- data/test/tem_unit/test_tem_crypto_hash.rb +35 -0
- data/test/tem_unit/test_tem_crypto_pstore.rb +53 -0
- data/test/tem_unit/test_tem_crypto_random.rb +25 -0
- data/test/tem_unit/test_tem_emit.rb +23 -0
- data/test/tem_unit/test_tem_memory.rb +48 -0
- data/test/tem_unit/test_tem_memory_compare.rb +65 -0
- data/test/tem_unit/test_tem_output.rb +32 -0
- data/test/tem_unit/test_tem_yaml_secpack.rb +47 -0
- data/test/test_driver.rb +108 -0
- data/test/test_exceptions.rb +35 -0
- data/test/transport/test_auto_configurator.rb +114 -0
- data/test/transport/test_java_card_mixin.rb +90 -0
- data/test/transport/test_jcop_remote.rb +82 -0
- data/timings/blank_bound_secpack.rb +18 -0
- data/timings/blank_sec.rb +14 -0
- data/timings/devchip_decrypt.rb +9 -0
- data/timings/post_buffer.rb +10 -0
- data/timings/simple_apdu.rb +5 -0
- data/timings/timings.rb +64 -0
- data/timings/vm_perf.rb +140 -0
- data/timings/vm_perf_bound.rb +141 -0
- metadata +201 -0
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'flexmock/test_unit'
|
5
|
+
|
6
|
+
require 'tem_ruby'
|
7
|
+
|
8
|
+
# Tests JcopRemoteProtocol, JcopRemoteServer, and JcopRemoteTransport.
|
9
|
+
class JcopRemoteTest < Test::Unit::TestCase
|
10
|
+
Protocol = Tem::Transport::JcopRemoteProtocol
|
11
|
+
Server = Tem::Transport::JcopRemoteServer
|
12
|
+
Transport = Tem::Transport::JcopRemoteTransport
|
13
|
+
|
14
|
+
# Serving logic that records what it receives and replays a log.
|
15
|
+
class Logic
|
16
|
+
include Protocol
|
17
|
+
attr_reader :received
|
18
|
+
def initialize(responses)
|
19
|
+
@responses = responses
|
20
|
+
@received = []
|
21
|
+
end
|
22
|
+
def connection_start
|
23
|
+
@received << :start
|
24
|
+
end
|
25
|
+
def connection_end
|
26
|
+
@received << :end
|
27
|
+
end
|
28
|
+
def exchange_apdu(apdu)
|
29
|
+
@received << apdu
|
30
|
+
@responses.shift
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def setup
|
35
|
+
@server = Server.new(:ip => '127.0.0.1', :port => 51995)
|
36
|
+
@client = Transport.new :host => '127.0.0.1', :port => 51995
|
37
|
+
@old_abort_on_exception = Thread.abort_on_exception
|
38
|
+
Thread.abort_on_exception = true
|
39
|
+
end
|
40
|
+
|
41
|
+
def teardown
|
42
|
+
Thread.abort_on_exception = @old_abort_on_exception
|
43
|
+
@server.stop
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_apdu_exchange
|
47
|
+
apdu_request = [0x31, 0x41, 0x59, 0x26, 0x53]
|
48
|
+
apdu_response = [0x27, 0x90, 0x00]
|
49
|
+
|
50
|
+
logic = Logic.new([apdu_response])
|
51
|
+
Thread.new do
|
52
|
+
begin
|
53
|
+
@server.run logic
|
54
|
+
rescue Exception
|
55
|
+
print $!, "\n"
|
56
|
+
print $!.backtrace.join("\n")
|
57
|
+
raise
|
58
|
+
end
|
59
|
+
end
|
60
|
+
Kernel.sleep 0.05 # Wait for the server to start up.
|
61
|
+
@client.connect
|
62
|
+
assert_equal apdu_response, @client.exchange_apdu(apdu_request)
|
63
|
+
@client.disconnect
|
64
|
+
Kernel.sleep 0.05 # Wait for the server to process the disconnect.
|
65
|
+
assert_equal [:start, apdu_request, :end], logic.received
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_java_card_integration
|
69
|
+
apdu_request = [0x00, 0x31, 0x41, 0x59, 0x00]
|
70
|
+
apdu_response = [0x27, 0x90, 0x00]
|
71
|
+
|
72
|
+
logic = Logic.new([apdu_response])
|
73
|
+
Thread.new { @server.run logic }
|
74
|
+
Kernel.sleep 0.05 # Wait for the server to start up.
|
75
|
+
@client.connect
|
76
|
+
assert_equal [0x27],
|
77
|
+
@client.applet_apdu!(:ins => 0x31, :p1 => 0x41, :p2 => 0x59)
|
78
|
+
@client.disconnect
|
79
|
+
Kernel.sleep 0.05 # Wait for the server to process the disconnect.
|
80
|
+
assert_equal [:start, apdu_request, :end], logic.received
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class TemTimings
|
2
|
+
def time_blank_bound_secpack
|
3
|
+
secpack = @tem.assemble { |s|
|
4
|
+
s.ldbc 0
|
5
|
+
s.outnew
|
6
|
+
s.halt
|
7
|
+
s.label :secret
|
8
|
+
s.zeros :tem_ubyte, 50
|
9
|
+
s.label :plain
|
10
|
+
s.zeros :tem_ubyte, 220
|
11
|
+
s.stack 1
|
12
|
+
}
|
13
|
+
secpack.bind @tem.pubek, :secret, :plain
|
14
|
+
|
15
|
+
print "SECpack has #{secpack.body.length} bytes, runs 3 instructions and produces 0 bytes\n"
|
16
|
+
do_timing { @tem.execute secpack }
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class TemTimings
|
2
|
+
def time_blank_sec
|
3
|
+
secpack = @tem.assemble { |s|
|
4
|
+
s.ldbc 0
|
5
|
+
s.outnew
|
6
|
+
s.halt
|
7
|
+
s.zeros :tem_ubyte, 70
|
8
|
+
s.stack 1
|
9
|
+
}
|
10
|
+
|
11
|
+
print "SECpack has #{secpack.body.length} bytes, runs 3 instructions and produces 0 bytes\n"
|
12
|
+
do_timing { @tem.execute secpack }
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
class TemTimings
|
2
|
+
def time_devchip_decrypt
|
3
|
+
pubek = @tem.pubek
|
4
|
+
data = (1...120).map { |i| (i * i * 217 + i * 661 + 393) % 256 }
|
5
|
+
encrypted_data = pubek.encrypt data
|
6
|
+
print "Encrypted blob has #{encrypted_data.length} bytes\n"
|
7
|
+
do_timing { @tem.devchip_decrypt encrypted_data, 0 }
|
8
|
+
end
|
9
|
+
end
|
data/timings/timings.rb
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'tem_ruby'
|
2
|
+
|
3
|
+
require 'timings/blank_bound_secpack.rb'
|
4
|
+
require 'timings/blank_sec.rb'
|
5
|
+
require 'timings/devchip_decrypt.rb'
|
6
|
+
require 'timings/post_buffer.rb'
|
7
|
+
require 'timings/simple_apdu.rb'
|
8
|
+
require 'timings/vm_perf.rb'
|
9
|
+
require 'timings/vm_perf_bound.rb'
|
10
|
+
|
11
|
+
class TemTimings
|
12
|
+
def setup
|
13
|
+
@tem = Tem.auto_tem
|
14
|
+
|
15
|
+
@tem.kill
|
16
|
+
@tem.activate
|
17
|
+
@tem.emit
|
18
|
+
end
|
19
|
+
|
20
|
+
def teardown
|
21
|
+
@tem.kill
|
22
|
+
@tem.disconnect if @tem
|
23
|
+
end
|
24
|
+
|
25
|
+
def do_timing
|
26
|
+
@tem.flush_buffers
|
27
|
+
|
28
|
+
n = 10
|
29
|
+
loop do
|
30
|
+
timings = (0...3).map do |i|
|
31
|
+
t_start = Time.now
|
32
|
+
n.times do
|
33
|
+
yield
|
34
|
+
end
|
35
|
+
t_delta = Time.now - t_start
|
36
|
+
end
|
37
|
+
avg_time = timings.inject { |a,v| a + v } / timings.length
|
38
|
+
max_diff = timings.map { |t| (t - avg_time).abs }.max
|
39
|
+
print "%8d: %3.8fs per run, %3.8fs uncertainty (%2.5f%%)\n" % [n, avg_time / n, max_diff / n, 100 * max_diff / avg_time]
|
40
|
+
|
41
|
+
return avg_time unless max_diff / avg_time >= 0.01
|
42
|
+
n *= 2
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.all_timings
|
47
|
+
timings = {}
|
48
|
+
t = TemTimings.new
|
49
|
+
t.setup
|
50
|
+
t.methods.select { |m| m =~ /time_/ }.each do |m|
|
51
|
+
print "Timing: #{m[5..-1]}...\n"
|
52
|
+
timings[m] = t.send m.to_sym
|
53
|
+
end
|
54
|
+
t.teardown
|
55
|
+
timings
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
if __FILE__ == $0
|
60
|
+
timings = TemTimings.all_timings
|
61
|
+
timings.map { |k, v| [k.to_s, v] }.sort.each do |timing|
|
62
|
+
print "#{timing.first}: #{'%.5f' % timing.last}s\n"
|
63
|
+
end
|
64
|
+
end
|
data/timings/vm_perf.rb
ADDED
@@ -0,0 +1,140 @@
|
|
1
|
+
class TemTimings
|
2
|
+
def time_vm_perf
|
3
|
+
secpack = @tem.assemble { |s|
|
4
|
+
s.ldwc 48 * 10
|
5
|
+
s.outnew
|
6
|
+
|
7
|
+
s.ldwc 10 # number of times to loop (4 instructions in loop)
|
8
|
+
s.label :main_loop
|
9
|
+
|
10
|
+
# arithmetic (18 instructions, 10 bytes out)
|
11
|
+
s.ldwc 0x1234
|
12
|
+
s.ldwc 0x5678
|
13
|
+
s.dupn :n => 2
|
14
|
+
s.add
|
15
|
+
s.outw
|
16
|
+
s.sub
|
17
|
+
s.outw
|
18
|
+
s.ldwc 0x0155
|
19
|
+
s.ldwc 0x02AA
|
20
|
+
s.mul
|
21
|
+
s.outw
|
22
|
+
s.ldwc 0x390C
|
23
|
+
s.ldwc 0x00AA
|
24
|
+
s.dupn :n => 2
|
25
|
+
s.div
|
26
|
+
s.outw
|
27
|
+
s.mod
|
28
|
+
s.outw
|
29
|
+
|
30
|
+
# memory (28 instructions, 16 bytes out)
|
31
|
+
s.ldwc 0x55AA
|
32
|
+
s.stw :clobber
|
33
|
+
s.ldb :clobber
|
34
|
+
s.outw
|
35
|
+
s.ldw :clobber
|
36
|
+
s.outw
|
37
|
+
s.ldbc 0xA5 - (1 << 8)
|
38
|
+
s.stb :clobber
|
39
|
+
s.ldw :clobber
|
40
|
+
s.outw
|
41
|
+
s.ldwc :clobber2
|
42
|
+
s.dupn :n => 1
|
43
|
+
s.dupn :n => 2
|
44
|
+
s.ldwc 0x9966 - (1 << 16)
|
45
|
+
s.stwv
|
46
|
+
s.ldbv
|
47
|
+
s.outw
|
48
|
+
s.ldbc 0x98 - (1 << 8)
|
49
|
+
s.stbv
|
50
|
+
s.ldwv
|
51
|
+
s.outw
|
52
|
+
s.ldwc 0x1122
|
53
|
+
s.ldwc 0x3344
|
54
|
+
s.ldwc 0x5566
|
55
|
+
s.flipn :n => 3
|
56
|
+
s.outw
|
57
|
+
s.outw
|
58
|
+
s.outw
|
59
|
+
|
60
|
+
# memory comparisons (22 instructions, 16 bytes out)
|
61
|
+
s.ldwc :const => 6
|
62
|
+
s.ldwc :cmp_med
|
63
|
+
s.ldwc :cmp_lo
|
64
|
+
s.mcmpvb
|
65
|
+
s.outw
|
66
|
+
s.mcmpfxb :size => 6, :op1 => :cmp_med, :op2 => :cmp_hi
|
67
|
+
s.outw
|
68
|
+
s.ldwc :const => 4
|
69
|
+
s.ldwc :cmp_lo
|
70
|
+
s.ldwc :cmp_med
|
71
|
+
s.mcmpvb
|
72
|
+
s.outw
|
73
|
+
s.mcfxb :size => 6, :from => :cmp_hi, :to => :copy_buf
|
74
|
+
s.pop
|
75
|
+
s.outfxb :size => 6, :from => :copy_buf
|
76
|
+
s.ldwc :const => 4
|
77
|
+
s.ldwc :cmp_hi
|
78
|
+
s.ldwc :copy_buf2
|
79
|
+
s.mcvb
|
80
|
+
s.pop
|
81
|
+
s.outfxb :size => 4, :from => :copy_buf2
|
82
|
+
|
83
|
+
# jumps (30 instructions, 6 bytes) from 6 * (5 instructions, 1 byte)
|
84
|
+
failed = 0xFA - (1 << 8)
|
85
|
+
[
|
86
|
+
[:ja, [1, 1, failed]],
|
87
|
+
[:jae, [1, 4, failed]],
|
88
|
+
[:jb, [1, failed, 7]],
|
89
|
+
[:jbe, [1, failed, 10]],
|
90
|
+
[:jz, [1, failed, 13]],
|
91
|
+
[:jne, [1, 16, failed]],
|
92
|
+
].each do |op_line|
|
93
|
+
op = op_line.shift
|
94
|
+
op_line.each_index do |i|
|
95
|
+
then_label = "#{op}_l#{i}_t".to_sym
|
96
|
+
out_label = "#{op}_l#{i}_o".to_sym
|
97
|
+
|
98
|
+
s.ldbc op_line[i][0]
|
99
|
+
s.send op, :to => then_label
|
100
|
+
s.ldbc op_line[i][2]
|
101
|
+
s.jmp :to => out_label
|
102
|
+
s.label then_label
|
103
|
+
s.ldbc op_line[i][1]
|
104
|
+
s.label out_label
|
105
|
+
s.outb
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
# loop back
|
110
|
+
s.ldbc 1
|
111
|
+
s.sub
|
112
|
+
s.dupn :n => 1
|
113
|
+
s.ja :to => :main_loop
|
114
|
+
|
115
|
+
s.label :done
|
116
|
+
s.halt
|
117
|
+
|
118
|
+
s.label :cmp_lo
|
119
|
+
s.data :tem_ubyte, [0xA3, 0x2C, 0x51, 0x63, 0x2C, 0x12]
|
120
|
+
s.label :cmp_med
|
121
|
+
s.data :tem_ubyte, [0xA3, 0x2C, 0x51, 0x63, 0x2D, 0x11]
|
122
|
+
s.label :cmp_hi
|
123
|
+
s.data :tem_ubyte, [0xA3, 0x2C, 0x51, 0x63, 0x2E, 0x10]
|
124
|
+
s.label :cmp_hi2
|
125
|
+
s.data :tem_ubyte, [0xA3, 0x2C, 0x51, 0x63, 0x2E, 0x10]
|
126
|
+
s.label :copy_buf
|
127
|
+
s.zeros :tem_ubyte, 6
|
128
|
+
s.label :copy_buf2
|
129
|
+
s.zeros :tem_ubyte, 4
|
130
|
+
s.label :clobber
|
131
|
+
s.zeros :tem_ubyte, 2
|
132
|
+
s.label :clobber2
|
133
|
+
s.zeros :tem_ubyte, 2
|
134
|
+
s.label :stack
|
135
|
+
s.stack 12
|
136
|
+
}
|
137
|
+
print "SECpack has #{secpack.body.length} bytes, runs 1020 instructions and produces 470 bytes\n"
|
138
|
+
do_timing { @tem.execute secpack }
|
139
|
+
end
|
140
|
+
end
|
@@ -0,0 +1,141 @@
|
|
1
|
+
class TemTimings
|
2
|
+
def time_vm_perf_bound
|
3
|
+
secpack = @tem.assemble { |s|
|
4
|
+
s.ldwc 48 * 10
|
5
|
+
s.outnew
|
6
|
+
|
7
|
+
s.ldwc 10 # number of times to loop (4 instructions in loop)
|
8
|
+
s.label :main_loop
|
9
|
+
|
10
|
+
# arithmetic (18 instructions, 10 bytes out)
|
11
|
+
s.ldwc 0x1234
|
12
|
+
s.ldwc 0x5678
|
13
|
+
s.dupn :n => 2
|
14
|
+
s.add
|
15
|
+
s.outw
|
16
|
+
s.sub
|
17
|
+
s.outw
|
18
|
+
s.ldwc 0x0155
|
19
|
+
s.ldwc 0x02AA
|
20
|
+
s.mul
|
21
|
+
s.outw
|
22
|
+
s.ldwc 0x390C
|
23
|
+
s.ldwc 0x00AA
|
24
|
+
s.dupn :n => 2
|
25
|
+
s.div
|
26
|
+
s.outw
|
27
|
+
s.mod
|
28
|
+
s.outw
|
29
|
+
|
30
|
+
# memory (28 instructions, 16 bytes out)
|
31
|
+
s.ldwc 0x55AA
|
32
|
+
s.stw :clobber
|
33
|
+
s.ldb :clobber
|
34
|
+
s.outw
|
35
|
+
s.ldw :clobber
|
36
|
+
s.outw
|
37
|
+
s.ldbc 0xA5 - (1 << 8)
|
38
|
+
s.stb :clobber
|
39
|
+
s.ldw :clobber
|
40
|
+
s.outw
|
41
|
+
s.ldwc :clobber2
|
42
|
+
s.dupn :n => 1
|
43
|
+
s.dupn :n => 2
|
44
|
+
s.ldwc 0x9966 - (1 << 16)
|
45
|
+
s.stwv
|
46
|
+
s.ldbv
|
47
|
+
s.outw
|
48
|
+
s.ldbc 0x98 - (1 << 8)
|
49
|
+
s.stbv
|
50
|
+
s.ldwv
|
51
|
+
s.outw
|
52
|
+
s.ldwc 0x1122
|
53
|
+
s.ldwc 0x3344
|
54
|
+
s.ldwc 0x5566
|
55
|
+
s.flipn :n => 3
|
56
|
+
s.outw
|
57
|
+
s.outw
|
58
|
+
s.outw
|
59
|
+
|
60
|
+
# memory comparisons (22 instructions, 16 bytes out)
|
61
|
+
s.ldwc :const => 6
|
62
|
+
s.ldwc :cmp_med
|
63
|
+
s.ldwc :cmp_lo
|
64
|
+
s.mcmpvb
|
65
|
+
s.outw
|
66
|
+
s.mcmpfxb :size => 6, :op1 => :cmp_med, :op2 => :cmp_hi
|
67
|
+
s.outw
|
68
|
+
s.ldwc :const => 4
|
69
|
+
s.ldwc :cmp_lo
|
70
|
+
s.ldwc :cmp_med
|
71
|
+
s.mcmpvb
|
72
|
+
s.outw
|
73
|
+
s.mcfxb :size => 6, :from => :cmp_hi, :to => :copy_buf
|
74
|
+
s.pop
|
75
|
+
s.outfxb :size => 6, :from => :copy_buf
|
76
|
+
s.ldwc :const => 4
|
77
|
+
s.ldwc :cmp_hi
|
78
|
+
s.ldwc :copy_buf2
|
79
|
+
s.mcvb
|
80
|
+
s.pop
|
81
|
+
s.outfxb :size => 4, :from => :copy_buf2
|
82
|
+
|
83
|
+
# jumps (30 instructions, 6 bytes) from 6 * (5 instructions, 1 byte)
|
84
|
+
failed = 0xFA - (1 << 8)
|
85
|
+
[
|
86
|
+
[:ja, [1, 1, failed]],
|
87
|
+
[:jae, [1, 4, failed]],
|
88
|
+
[:jb, [1, failed, 7]],
|
89
|
+
[:jbe, [1, failed, 10]],
|
90
|
+
[:jz, [1, failed, 13]],
|
91
|
+
[:jne, [1, 16, failed]],
|
92
|
+
].each do |op_line|
|
93
|
+
op = op_line.shift
|
94
|
+
op_line.each_index do |i|
|
95
|
+
then_label = "#{op}_l#{i}_t".to_sym
|
96
|
+
out_label = "#{op}_l#{i}_o".to_sym
|
97
|
+
|
98
|
+
s.ldbc op_line[i][0]
|
99
|
+
s.send op, :to => then_label
|
100
|
+
s.ldbc op_line[i][2]
|
101
|
+
s.jmp :to => out_label
|
102
|
+
s.label then_label
|
103
|
+
s.ldbc op_line[i][1]
|
104
|
+
s.label out_label
|
105
|
+
s.outb
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
# loop back
|
110
|
+
s.ldbc 1
|
111
|
+
s.sub
|
112
|
+
s.dupn :n => 1
|
113
|
+
s.ja :to => :main_loop
|
114
|
+
|
115
|
+
s.label :done
|
116
|
+
s.halt
|
117
|
+
|
118
|
+
s.label :cmp_lo
|
119
|
+
s.data :tem_ubyte, [0xA3, 0x2C, 0x51, 0x63, 0x2C, 0x12]
|
120
|
+
s.label :cmp_med
|
121
|
+
s.data :tem_ubyte, [0xA3, 0x2C, 0x51, 0x63, 0x2D, 0x11]
|
122
|
+
s.label :cmp_hi
|
123
|
+
s.data :tem_ubyte, [0xA3, 0x2C, 0x51, 0x63, 0x2E, 0x10]
|
124
|
+
s.label :cmp_hi2
|
125
|
+
s.data :tem_ubyte, [0xA3, 0x2C, 0x51, 0x63, 0x2E, 0x10]
|
126
|
+
s.label :copy_buf
|
127
|
+
s.zeros :tem_ubyte, 6
|
128
|
+
s.label :copy_buf2
|
129
|
+
s.zeros :tem_ubyte, 4
|
130
|
+
s.label :clobber
|
131
|
+
s.zeros :tem_ubyte, 2
|
132
|
+
s.label :clobber2
|
133
|
+
s.zeros :tem_ubyte, 2
|
134
|
+
s.label :stack
|
135
|
+
s.stack 12
|
136
|
+
}
|
137
|
+
secpack.bind @tem.pubek, :done, :stack
|
138
|
+
print "SECpack has #{secpack.body.length} bytes, runs 1020 instructions and produces 470 bytes\n"
|
139
|
+
do_timing { @tem.execute secpack }
|
140
|
+
end
|
141
|
+
end
|