;; ------------------------------------------------ ;; poker.s for Mac OS X (PowerPC 32bit) ;; % as -o poker.o poker.s && gcc poker.o -o poker ;; ------------------------------------------------ .machine ppc .globl _main ;; レジスタ ;; ;; r4: char *argv[] ;; r5: 残りカードの枚数 ;; r6: スキャンする文字(スートか数字) ;; r7: スート役(フラッシュ)フラグ(役候補スートのASCIIコードが入る) ;; r8: ノーペアの数字用フラグ(13ビット使用) ;; r9: ワンペア、ツーペア用フラグ(13ビット使用) ;; r10: スリーカード用フラグ(13ビット使用) ;; r11: フォーカード用フラグ(13ビット使用) ;; _main: ;; レジスタの初期化 addi r4, r4, 4 ; argv[1] にポインタを進める lwz r4, 0(r4) ; argv[1] の文字列をレジスタにロード li r5, 5 ; 残りカード5枚 li r7, 0 li r8, 0 li r9, 0 li r10, 0 li r11, 0 _scan_card: ;; 一文字目(スート) lbz r6, 0(r4) bl _scan_suit ; サブルーチン addi r4, r4, 1 ;; 二文字目(数字) lbz r6, 0(r4) bl _scan_rank ; サブルーチン ;; 繰り返しの準備 subi r5, r5, 1 cmpli cr7, r5, 0 beq cr7, _show_hand ; 5枚チェックし終えたら役を表示する addi r4, r4, 1 b _scan_card ; 繰り返し ;; スートのスキャン _scan_suit: ;; 最初のカードならそのままフラグをセット cmpli cr7, r5, 5 beq cr7, _scan_first_suit ;; 二枚目以降 cmpli cr7, r7, 0 ; フラグがゼロならフラッシュの可能性もゼロ beqlr cr7 cmpl cr7, r7, r6 ; 前のスートと同じなら戻る beqlr cr7 li r7, 0 ; 前のスートと異なるならフラグをクリア blr ; サブルーチン終了 ;; 最初のカードのスートのスキャン _scan_first_suit: add r7, r0, r6 ; r0 は 0 とみなされるので、r7 = r6 blr ; サブルーチン終了 ;; ランクのスキャン _scan_rank: ;; ASCIIコードを 0-12 の整数にする cmpli cr7, r6, 65 ; 'A' beq cr7, _scan_rank_ace cmpli cr7, r6, 84 ; 'T' beq cr7, _scan_rank_ten cmpli cr7, r6, 74 ; 'J' beq cr7, _scan_rank_jack cmpli cr7, r6, 81 ; 'Q' beq cr7, _scan_rank_queen cmpli cr7, r6, 75 ; 'K' beq cr7, _scan_rank_king ;; 2-9 subi r6, r6, 49 b _scan_rank_body _scan_rank_ace: li r6, 0 b _scan_rank_body _scan_rank_ten: li r6, 9 b _scan_rank_body _scan_rank_jack: li r6, 10 b _scan_rank_body _scan_rank_queen: li r6, 11 b _scan_rank_body _scan_rank_king: li r6, 12 b _scan_rank_body ;; r15: ランクのビット表現 ;; r16: 論理演算結果 _scan_rank_body: li r0, 1 slw r15, r0, r6 ; 左シフト (1< 0 にして戻る _check_straight: ;; ビットマスク 11111 を左にずらしながら9回AND演算する li r0, (1<<5)-1 ; ビットマスク li r2, 0 ; 左シフト数 _find_straight: slw r15, r0, r2 ; 左シフト and r17, r8, r15 ; ノーペア用フラグを調べる cmpl cr7, r17, r15 beq cr7, _found_straight addi r2, r2, 1 ; 次のループの準備 cmpli cr7, r2, 9 ble cr7, _find_straight li r2, 0 ; 5つの連続した数字がなかった blr ; サブルーチン終了 _found_straight: li r2, 1 ; 5つの連続した数字を発見 blr ; サブルーチン終了 ;; フルハウスかスリーカード _check_full_house_or_three_kind: ;; ワンペアがあればフルハウス andi. r0, r9, 8191 cmpli cr7, r0, 0 bgt cr7, _show_full_house b _show_three_kind ;; ワンペアかツーペア _check_one_or_two_pair: li r0, 1 ; これをシフト li r2, 0 ; 左シフト数 li r16, 0 ; ペアの数 ;; ペア用フラグからペアの数をカウントする _find_pairs: slw r15, r0, r2 and r17, r9, r15 addi r2, r2, 1 cmpli cr7, r17, 0 bgt cr7, _found_pair cmpli cr7, r2, 13 ; 0-12 の 13 回チェック ble cr7, _find_pairs ;; ペアの数で分岐 cmpli cr7, r16, 1 beq cr7, _show_one_pair b _show_two_pair ;; 見つけたペアの数を増加 _found_pair: addi r16, r16, 1 b _find_pairs ; 戻る ;; ノーペア _show_no_pair: lis r4, hi16(no_pair) addi r4, r4, lo16(no_pair) li r5, 8 b _print_and_exit ;; ワンペア _show_one_pair: lis r4, hi16(one_pair) addi r4, r4, lo16(one_pair) li r5, 9 b _print_and_exit ;; ツーペア _show_two_pair: lis r4, hi16(two_pair) addi r4, r4, lo16(two_pair) li r5, 9 b _print_and_exit ;; スリーカード _show_three_kind: lis r4, hi16(three_kind) addi r4, r4, lo16(three_kind) li r5, 16 b _print_and_exit ;; ストレート _show_straight: lis r4, hi16(straight) addi r4, r4, lo16(straight) li r5, 9 b _print_and_exit ;; フラッシュ _show_flush: lis r4, hi16(flush) addi r4, r4, lo16(flush) li r5, 6 b _print_and_exit ;; フルハウス _show_full_house: lis r4, hi16(full_house) addi r4, r4, lo16(full_house) li r5, 11 b _print_and_exit ;; ストレートフラッシュ _show_straight_flush: lis r4, hi16(straight_flush) addi r4, r4, lo16(straight_flush) li r5, 15 b _print_and_exit ;; フォーカード _show_four_kind: lis r4, hi16(four_kind) addi r4, r4, lo16(four_kind) li r5, 15 b _print_and_exit ;; ロイヤルフラッシュ _show_royal_flush: lis r4, hi16(royal_flush) addi r4, r4, lo16(royal_flush) li r5, 12 b _print_and_exit ;; 文字列を出力して終了する ;; r4 に文字列のアドレスを、r5 に文字列の長さをセットしておく _print_and_exit: ;; sys_write() li r3, 1 ; 標準出力 li r0, 4 ; sys_write sc ; 呼び出し b _exit _exit: ;; sys_exit() li r3, 0 li r0, 1 sc ;; 定数 .data .align 2 no_pair: .asciz "No pair\n" .align 2 one_pair: .asciz "One pair\n" .align 2 two_pair: .asciz "Two pair\n" .align 2 three_kind: .asciz "Three of a kind\n" .align 2 straight: .asciz "Straight\n" .align 2 flush: .asciz "Flush\n" .align 2 full_house: .asciz "Full house\n" .align 2 four_kind: .asciz "Four of a kind\n" .align 2 straight_flush: .asciz "Straight flush\n" .align 2 royal_flush: .asciz "Royal flush\n" .align 2