szktty #5325(2008/01/14 18:50 GMT) [ Other ] Rating0/0=0.00
Mac OS X (PowerPC 32bit) アセンブリで。お題の通り一京未満しか対応してません。
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
.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
Rating0/0=0.00-0+
[ reply ]
szktty
#5325()
[
Other
]
Rating0/0=0.00
Mac OS X (PowerPC 32bit) アセンブリで。お題の通り一京未満しか対応してません。
.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 4Rating0/0=0.00-0+
[ reply ]