Add tags

Add tags to the following comment

Mac OS X (PowerPC 32bit) アセンブリで。コマンドラインでBFのソースを書いて、標準出力にアセンブリを出力します。当方ヘタレなもんで、Mac OS X PowerPCアセンブリでのファイルの扱いがよくわかりません。

# BFコンパイラのコンパイル
% gcc -o bfc-osxppc bfc-osxppc.s
% ./bfc-osxppc "++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+." > hello-bf.s

# 出力されたソースのコンパイルと実行
% gcc -o hello-bf hello-bf.s
% ./hello-bf
Hello World!
  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
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
;; % gcc -o bfc-osxppc bfc-osxppc.s
;; 
;; Usage: ./bfc-osxppc "source..." > output
;;
;; ex)
;; % ./bfc-osxppc "++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+." > hello-bf.s
;; % gcc -o hello-bf hello-bf.s
;; % ./hello-bf
;; Hello World!

        .machine ppc
        .globl _main
        
        .macro  PUSH
                stwu    r3, -4(r1)
                stwu    r4, -4(r1)
                stwu    r5, -4(r1)
                stwu    r6, -4(r1)
                stwu    r7, -4(r1)
                stwu    r8, -4(r1)
                stwu    r9, -4(r1)
                stwu    r10, -4(r1)
                stwu    r11, -4(r1)
                stwu    r12, -4(r1)
                stwu    r13, -4(r1)
                mflr    r20
                stwu    r20, -4(r1)
        .endmacro

        .macro POP
                lwz     r20, 0(r1)
                mtlr    r20
                lwzu    r13, 4(r1)
                lwzu    r12, 4(r1)
                lwzu    r11, 4(r1)
                lwzu    r10, 4(r1)
                lwzu    r9, 4(r1)
                lwzu    r8, 4(r1)
                lwzu    r7, 4(r1)
                lwzu    r6, 4(r1)
                lwzu    r5, 4(r1)
                lwzu    r4, 4(r1)
                lwzu    r3, 4(r1)
                addi    r1, r1, 4
        .endmacro

        .macro PRINT
                PUSH
                li      r3, 1
                lis     r4, hi16($0)
                addi    r4, r4, lo16($0)
                lis     r5, hi16($0_len)
                addi    r5, r5, lo16($0_len)
                li      r0, 4
                sc
                POP
        .endmacro

        .macro PRINT_DIGIT
                PUSH
                mr      r3, $0
                bl      print_digit
                POP
        .endmacro

;; r7:  ソースコード
;; r8:  読み込んだ文字
;; r9:  配列のサイズ
;; r10: ラベルの数
_main:
        lwz     r7, 4(r4)       ; argv[1]
        li      r8, 0
        li      r9, 10
        li      r10, 0

;; ヘッダを出力
print_header:
        PRINT   bf_header

compile:
        lbz     r8, 0(r7)
        cmpli   cr7, r8, 0
        beq     cr7, finish_compile
        addi    r7, r7, 1

        cmpli   cr7, r8, 62     ; '>'
        beq     cr7, compile_inc
        cmpli   cr7, r8, 60     ; '<'
        beq     cr7, compile_dec
        cmpli   cr7, r8, 43     ; '+'
        beq     cr7, compile_plus
        cmpli   cr7, r8, 45     ; '-'
        beq     cr7, compile_minus
        cmpli   cr7, r8, 46     ; '.'
        beq     cr7, compile_output
        cmpli   cr7, r8, 44     ; ','
        beq     cr7, compile_input
        cmpli   cr7, r8, 91     ; '['
        beq     cr7, compile_forward
        cmpli   cr7, r8, 93     ; ']'
        beq     cr7, compile_backward

        ;; 他の文字は無視
        b       compile

compile_inc:
        addi    r9, r9, 1
        PRINT   bf_inc
        b       compile

compile_dec:
        subi    r9, r9, 1
        PRINT   bf_dec
        b       compile

compile_plus:
        PRINT   bf_plus
        b       compile

compile_minus:
        PRINT   bf_minus
        b       compile

compile_output:
        PRINT   bf_output
        b       compile

compile_input:
        PRINT   bf_input
        b       compile

compile_forward:
        addi    r10, r10, 1
        stwu    r10, -4(r1)
        PRINT   bf_forward_cmp
        PRINT   bf_end_label
        PRINT_DIGIT     r10
        PRINT   lf
        PRINT   bf_begin_label
        PRINT_DIGIT     r10
        PRINT   bf_label_term
        b       compile

compile_backward:
        lwz     r2, 0(r1)
        addi    r1, r1, 4
        PRINT   bf_backward_cmp
        PRINT   bf_begin_label
        PRINT_DIGIT     r2
        PRINT   lf
        PRINT   bf_end_label
        PRINT_DIGIT     r2
        PRINT   bf_label_term
        b       compile

finish_compile:
        PRINT   lf
        PRINT   bf_exit
        PRINT   bf_data
        PRINT   bf_array_decl

print_array:
        PRINT   bf_array_element
        cmpli   cr7, r9, 0
        subi    r9, r9, 1
        bgt     cr7, print_array
        PRINT   bf_array_decl_end
        
exit:
        PRINT   lf
        
        ;; sys_exit()
        li      r3, 0
        li      r0, 1           ; sys_exit
        sc


;; 正の整数を10進数で出力
;; r3: 出力する整数
print_digit:
        mr      r10, r3
        li      r11, 25000      ; fig, 桁
        mulli   r11, r11, 4
        li      r14, 10         ; 桁の除算用
        li      r15, 0          ; 残りの数字をすべて表示するか

;; 上の桁から順に出力する
print_each_digit:
        divw    r12, r10, r11   ; d = i / fig
        mullw   r13, r11, r12   ; rem = i - fig * d
        sub     r10, r10, r13

        cmpli   cr7, r15, 0
        cmpli   cr6, r12, 0     ; d == 0
        cmpli   cr5, r11, 1     ; fig > 1
        crand   2, 30, 26       ; cr0[eq] = cr7[eq] && cr6[eq]
        crand   2, 2, 21        ; cr0[eq] = cr0[eq] && cr5[gt]
        divw    r11, r11, r14   ; fig /= 10
        beq     cr0, print_each_digit

        ;; 出力
        li      r15, 1
        addi    r12, r12, 48    ; ASCIIコードにする
        li      r3, 1           ; 標準出力
        lis     r4, hi16(temp)
        addi    r4, r4, lo16(temp)
        li      r5, 1
        li      r0, 4           ; sys_write
        stb     r12, 0(r4)
        PUSH
        sc
        POP

        cmpli   cr7, r11, 0     ; fig == 0 なら終了
        beqlr   cr7
        b       print_each_digit


;; 定数

        .data
        .align  4

temp:
        .asciz  "    "
        .align  4

lf:
        .asciz  "\n"
        .align  4
        lf_len = 1
        .align  4

bf_header:
        .asciz  ";; This file is automatically generated. Do not edit.\n\n    .machine ppc\n    .globl _main\n\n    .macro  PUSH\n            stwu    r7, -4(r1)\n            stwu    r8, -4(r1)\n            stwu    r9, -4(r1)\n    .endmacro\n\n    .macro  POP\n            lwz     r9, 0(r1)\n            lwzu    r8, 4(r1)\n            lwzu    r7, 4(r1)\n            addi    r1, r1, 4\n    .endmacro\n\n    .macro  OUTPUT\n            PUSH\n            li      r3, 1\n            lis     r4, hi16(temp)\n            addi    r4, r4, lo16(temp)\n            stb     r8, 0(r4)\n            li      r5, 1\n            li      r0, 4\n            sc\n            POP\n    .endmacro\n\n\n_main:\n    lis     r7, hi16(array)\n    addi    r7, r7, lo16(array)\n    li      r8, 0\n\n"
        bf_header_len = . - bf_header - 1
        .align  4

bf_exit:
        .asciz  "exit:\n    li      r8, 10\n    OUTPUT\n    li      r3, 0\n    li      r0, 1\n    sc\n\n"
        bf_exit_len = . - bf_exit - 1
        .align  4

bf_data:
        .asciz  "\n\n    .data\n    .align  4\n\ntemp:\n    .asciz  \"  \"\n    .align  4\n\n"
        bf_data_len = . - bf_data - 1
        .align  4

bf_array_decl:
        .asciz  "array:\n    .long "
        bf_array_decl_len = . - bf_array_decl - 1
        .align  4

bf_array_element:
        .asciz  "0, "
        bf_array_element_len = . - bf_array_element - 1
        .align  4

bf_array_decl_end:
        .asciz  "0\n    .align  4\n"
        bf_array_decl_end_len = . - bf_array_decl_end - 1
        .align  4

bf_inc:
        .asciz  "    addi    r7, r7, 4\n"
        bf_inc_len = . - bf_inc - 1
        .align  4

bf_dec:
        .asciz  "    subi    r7, r7, 4\n"
        bf_dec_len = . - bf_dec - 1
        .align  4

bf_plus:
        .asciz  "    lwz     r8, 0(r7)\n    addi    r8, r8, 1\n    stw     r8, 0(r7)\n"
        bf_plus_len = . - bf_plus - 1
        .align  4

bf_minus:
        .asciz  "    lwz     r8, 0(r7)\n    subi    r8, r8, 1\n    stw     r8, 0(r7)\n"
        bf_minus_len = . - bf_minus - 1
        .align  4

bf_output:
        .asciz  "    lwz     r8, 0(r7)\n    OUTPUT\n"
        bf_output_len = . - bf_output - 1
        .align  4

bf_input:
        .asciz  "    INPUT\n"
        bf_input_len = . - bf_input - 1
        .align  4

bf_forward_cmp:
        .asciz  "    lwz     r8, 0(r7)\n    cmpi    cr7, r8, 0\n    beq     cr7, "
        bf_forward_cmp_len = . - bf_forward_cmp - 1
        .align  4

bf_begin_label:
        .asciz  "begin"
        bf_begin_label_len = . - bf_begin_label - 1
        .align  4

bf_end_label:
        .asciz  "end"
        bf_end_label_len = . - bf_end_label - 1
        .align  4

bf_label_term:
        .asciz  ":\n"
        bf_label_term_len = . - bf_label_term - 1
        .align  4

bf_backward_cmp:
        .asciz  "    lwz     r8, 0(r7)\n    cmpi    cr7, r8, 0\n    bne     cr7, "
        bf_backward_cmp_len = . - bf_backward_cmp - 1
        .align  4

Add tags

The input will be splited to tags with space.

Index

Feed

Other

Link

Pathtraq

loading...