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终止字符串,输出将输出到stdout。在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.