.machine ppc .globl _main ;; Usage: ./kansuuji string ;; r3: 数字 ;; r4: 桁数 ;; r5: 処理中の数字 ;; r6: 開始時のスタックの位置 ;; r7: 漢数字(零〜九) ;; r8: 漢数字の桁1(十百千) ;; r9: 漢数字の桁2(万〜) ;; r11: 表示文字数 ;; r12: フラグ ;; 1: 桁1をスタックに積んだかどうか ;; 2: 桁2をスタックに積んだかどうか _main: lwz r3, 4(r4) ; argv[1] li r4, 0 mr r6, r1 ; スタックポインタを保存 lis r7, hi16(digit) addi r7, r7, lo16(digit) ;; 文字列の最後にセット lis r8, hi16(subunit_end) addi r8, r8, lo16(subunit_end) lis r9, hi16(unit_end) addi r9, r9, lo16(unit_end) ;; 改行をスタックに積んでおく li r11, 1 ; 表示文字数(改行含む) li r0, 10 ; '\n' stbu r0, -1(r1) goto_end: ;; 文字列の最後に移動 addi r4, r4, 1 lbz r5, 0(r3) addi r3, r3, 1 cmpli cr7, r5, 0 bne cr7, goto_end subi r3, r3, 2 ; 文字列の終端から戻す subi r4, r4, 1 mr r13, r4 scan: li r12, 0 ; フラグをクリア ;; 桁1 lbz r0, 0(r8) cmpli cr7, r0, 0 bne cr7, push_subunit ;; 桁1のポインタを先頭に戻し、桁2へ lis r8, hi16(subunit) addi r8, r8, lo16(subunit) b push_unit ;; 桁1 push_subunit: lbz r0, 1(r8) stbu r0, -1(r1) lbz r0, 0(r8) stbu r0, -1(r1) addi r8, r8, 2 addi r11, r11, 2 ; 表示文字数+2 li r12, 1 ; フラグ b push_digit ;; 桁2 push_unit: lbz r0, 0(r9) cmpli cr7, r0, 0 beq cr7, ignore_unit ;; 桁2をスタックに追加 lbz r0, 1(r9) stbu r0, -1(r1) lbz r0, 0(r9) stbu r0, -1(r1) addi r9, r9, 2 addi r11, r11, 2 ; 表示文字数+2 li r12, 2 ; フラグ b push_digit ignore_unit: lis r9, hi16(unit) addi r9, r9, lo16(unit) push_digit: ;; 整数に変換してスタックに追加 lbz r5, 0(r3) subi r5, r5, 48 ; ASCIIコード ;; 数字が1で、かつ桁1がある場合は1を省略 cmpli cr7, r5, 1 cmpli cr6, r12, 1 crand 2, 30, 26 ; cr0[eq] = cr7[eq] & cr6[eq] beq cr0, next_scan ;; 数字が0で、かつ一の位であれば省略 cmpli cr7, r5, 0 cmpl cr6, r13, r4 crand 2, 30, 26 ; cr0[eq] = cr7[eq] & cr6[eq] beq cr0, next_scan ;; 数字が0で、かつ桁2がある場合は数字だけ省略 cmpli cr7, r5, 0 cmpli cr6, r12, 2 crand 2, 30, 26 ; cr0[eq] = cr7[eq] & cr6[eq] beq cr0, next_scan ;; 数字が0で、かつ桁1がある場合は両方省略 cmpli cr7, r5, 0 cmpli cr6, r12, 1 crand 2, 30, 26 ; cr0[eq] = cr7[eq] & cr6[eq] bne cr0, push_digit_exec addi r1, r1, 2 ; 先に積んである桁を戻す subi r11, r11, 2 b next_scan push_digit_exec: ;; 数字 add r10, r7, r5 add r10, r10, r5 ; 2バイト分 lbz r0, 1(r10) stbu r0, -1(r1) lbz r0, 0(r10) stbu r0, -1(r1) addi r11, r11, 2 next_scan: subi r3, r3, 1 subi r4, r4, 1 cmpli cr7, r4, 0 bgt cr7, scan ;; 表示 stwu r6, -4(r1) ; スタックに退避 li r3, 1 addi r4, r1, 4 mr r5, r11 li r0, 4 ; sys_write() sc lwz r6, 0(r1) ; スタックから復帰 addi r1, r1, 4 exit: ;; 終了 mr r1, r6 ; スタックポインタを戻す li r3, 0 li r0, 1 sc .data .align 4 digit: .asciz "零一二三四五六七八九" .align 4 subunit: .asciz "十百千" subunit_end = . - 1 .align 4 unit: .asciz "万億兆" unit_end = . - 1 .align 4