Comment detail

コマンドライン引数の取得 (Nested Flatten)

Mac OS X (PowerPC 32bit) アセンブリで。Mac OS X (PowerPC) のアセンブリでは、関数の引数はレジスタ r3-r10 に入ります。あとはmain関数の引数を操作するだけです。

 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
        ;; Mac OS X (PowerPC 32bit)
        ;; % as -o cmdline.o cmdline.s && gcc cmdline.o -o cmdline
        .machine ppc
        .globl _main

_main:
        ;; r3 = int argc
        ;; r4 = char *argv[]
        ;; それぞれ r6, r7 にコピーしておく
        mr      r6, r3
        mr      r7, r4

_print_arg:
        ;; まず、文字列の長さをカウントする
        lwz     r4, 0(r7)       ; カウント用文字列
        li      r5, 0           ; 長さの初期化

_count_strlen:
        lbz     r0, 0(r4)       ; 1文字レジスタに移す
        cmpli   cr7, r0, 0
        beq     cr7, _print_arg_write
        addi    r4, r4, 1
        addi    r5, r5, 1
        b       _count_strlen

_print_arg_write:
        ;; 引数文字列の表示

        ;; 引数の残数をスタックに退避
        ;; sys_write() を呼ぶたびに実行
        subi    r1, r1, 4
        stw     r6, 0(r1)

        ;; sys_write()
        ;; r5 は _count_strlen で既に代入済み
        li      r3, 1           ; 標準出力
        lwz     r4, 0(r7)       ; 出力する文字列
        li      r0, 4           ; sys_write
        sc                      ; 呼び出し

        ;; スタックから引数の残数を復帰
        lwz     r6, 0(r1)
        addi    r1, r1, 4

        ;; 引数の残数をスタックに退避
        subi    r1, r1, 4
        stw     r6, 0(r1)

        ;; スペースを出力
        li      r3, 1           ; 標準出力
        li      r4, hi16(space)
        addi    r4, r4, lo16(space)
        li      r5, 1           ; 出力する文字列の長さ
        li      r0, 4           ; sys_write
        sc                      ; 呼び出し

        ;; スタックから引数の残数を復帰
        lwz     r6, 0(r1)
        addi    r1, r1, 4

        ;; 繰り返しの終了条件判断
        subi    r6, r6, 1       ; カウント減
        cmpi    cr7, r6, 0
        beq     cr7, _end
        addi    r7, r7, 4       ; 引数文字列のポインタを一つ進める
        b       _print_arg      ; 次の引数へ

_end:
        ;; 改行を出力
        li      r3, 1           ; 標準出力
        li      r4, hi16(lf)
        addi    r4, r4, lo16(lf)
        li      r5, 1
        li      r0, 4           ; sys_write
        sc                      ; 呼び出し

        ;; sys_exit()                                                             
        li      r3, 0
        li      r0, 1
        sc

        .data
        .align  2

space:
        .asciz  " "

lf:
        .asciz  "\n"

Index

Feed

Other

Link

Pathtraq

loading...