Linux上のARMマシンコード、50バイト
六角ダンプ:
b580 1e41 f811 2f01 2a00 d1fb 3901 780b 1a0a 4601 2001 2704 df00 2000 a103 2202 f013 0303 2b03 4159 df00 bd80 2e202f5c 5c2f
ここに最初の投稿をしてください。これは32ビットARMアセンブリ、特にThumb-2です。入力文字列は、r0から取り込まれたNUL終了文字列であり、出力は標準出力に出力されます。C構文では、関数のプロトタイプはvoid func_name(char * string)になります。AAPCS(ARM呼び出し規約)の不満です。そうでなければ、2バイトを削ることができます。
以下は、何が起こっているのかを説明するコメント付きの同等のアセンブリです。
@Input: r0 is char* (the string)
@Output: Modified string to console
push {r7,lr} @Save r7 and the link register
subs r1,r0,#1 @Make a copy of the char*, subtracting because we're
@going to pre-increment.
loop: @This loop is a little strlen routine
ldrb r2,[r1,#1]! @In C-syntax, r2=*++r1;
cmp r2,#0
bne loop
@Now r1 points to the null character that terminates the string
subs r1,r1,#1 @Make r1 point to the last character
ldrb r3,[r1] @Load the last character into r3
subs r2,r1,r0 @r2=length(r0) - 1;
mov r1,r0 @r0 holds the original char*
movs r0,#1 @1 is the file descriptor for stdout
movs r7,#4 @4 is write
swi #0
@Now all the characters from the initial string have been printed,
@except for the last one, which is currently in r3.
movs r0,#1 @1 is stdout, have to reload this since the system call
@returns in r0.
adr r1,msg @Load msg into r1 (the pointer to the string)
movs r2,#2 @We're going to print two more characters.
@Now the bit magic. The ascii codes for '\', '.', and '/' map onto
@0, 2, and 3 when bitwise anded with 3 (0b11).
@This will be the offset into our string. However, since we must print
@2 characters, we need our offsets to be 0, 2, and 4.
@Therefore, we only set the carry if our value is >=3, then add with
@carry (adcs). Thus we get the correct offset into the string msg.
ands r3,r3,#3
cmp r3,#3 @Sets carry if r3>=3
adcs r1,r1,r3 @Add the offset to r1
swi #0 @Make the system call
pop {r7,pc} @Return and restore r7
msg:
.ascii "\\/ ./\\" @The three different sequences of 2 characters that
@can go at the end.