Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 臂装配环_Assembly_For Loop_Arm - Fatal编程技术网

Assembly 臂装配环

Assembly 臂装配环,assembly,for-loop,arm,Assembly,For Loop,Arm,for(int i=0;i

for(int i=0;i<10000;i++)
a[i]=b[i]+c[i]
mov r0,#0x2700
orr r0,#0x0010
顶部:
ldr r1,[r9],#4
ldr r2,[r10],#4
加上r1,r1,r2
str r1,[r8],#4
潜艇r0#1
bne陀螺

假设这种高级语言与C语言没有任何冲突,您可以使用arm C编译器从代码段创建汇编代码。例如,如果在test.c中有以下内容

for (int i = 0; i < 10000; i++)
  a[i] = b[i] + c[i]



mov r0,#0x2700
orr r0,#0x0010
top:
ldr r1,[r9],#4
ldr r2,[r10],#4
add r1,r1,r2
str r1,[r8],#4
subs r0,#1
bne top
创建一个test.s文件,该文件将包含测试函数的汇编代码以及一些额外的内容。您可以在下面看到循环是如何编译成程序集的

arm-linux-androideabi-gcc -O0 -S test.c

.L3:
mov r2,r8
mov r3,r0
mov r3、r3、asl#2
加上r3,r2,r3
mov r1,r9
mov r2,r0
移动r2,r2,asl#2
加上r2,r1,r2
ldr r1,[r2,#0]
移动ip,sl
mov r2,r0
移动r2,r2,asl#2
加上r2,ip,r2
ldr r2,[r2,#0]
加上r2,r1,r2
str r2[r3,#0]
mov r3,r0
加上r3,r3,#1
mov r0,r3
.L2:
mov r2,r0
ldr r3、.L5
cmp r2,r3
B.L3
副警司,fp,#12
ldmfd sp!,{r8,r9,sl,fp}
bx-lr
现在,这种方法的问题在于相信编译器会为您的研究生成最佳代码,这可能并不总是如此,但您将得到上述问题的快速答案,而不是等待别人:)

--额外的--

GCC允许您将变量放入特定寄存器,请参阅

您可以获得arm说明备忘单


更新版本的GCC创建了更好的arm代码。上面的截图是由版本4.4.3生成的,我可以确认版本4.7.1证明了我的说法。因此,如果您采用我的方法,请使用您能获得的最新工具链。

以@alpera的答案为基础,您也可以展开循环,一次执行4个操作,尽管您是否获得性能优势取决于分支周围的内存访问或管道暂停是更大的影响

<snipped>
.L3:
        mov     r2, r8
        mov     r3, r0
        mov     r3, r3, asl #2
        add     r3, r2, r3
        mov     r1, r9
        mov     r2, r0
        mov     r2, r2, asl #2
        add     r2, r1, r2
        ldr     r1, [r2, #0]
        mov     ip, sl
        mov     r2, r0
        mov     r2, r2, asl #2
        add     r2, ip, r2
        ldr     r2, [r2, #0]
        add     r2, r1, r2
        str     r2, [r3, #0]
        mov     r3, r0
        add     r3, r3, #1
        mov     r0, r3
.L2:
        mov     r2, r0
        ldr     r3, .L5
        cmp     r2, r3
        ble     .L3
        sub     sp, fp, #12
        ldmfd   sp!, {r8, r9, sl, fp}
        bx      lr
<snipped>
如果您手头有NEON单元,我们也可以这样做——在这种情况下,它将并行加载、存储和添加——实际上将问题减少到5条指令,这些指令同时执行两次循环迭代


默认情况下,C编译器不会生成如此紧凑的代码(或NEON的并行化),因为它必须假设用于读取和写入(r8、r10和r11)的缓冲区可能会重叠-因此通过r8写入的代码可能会在通过r9或r10的循环的下一次迭代中立即读取。您可以使用C++中的
restrict
\uu restrict
)修饰符告诉编译器情况并非如此。

您可能想澄清一下您在这里的问题-ARM风格的汇编和Android编程是两件完全不同的事情;Android是类似Java的VM风格的环境;无法使用程序集,因为代码由运行时解释,而不是直接在处理器上运行;你是怎么尝试的;你在使用什么软件/设备?它不一定适用于Android。我只想体验一下在移动设备上运行的ARM组件。这里需要一定剂量的盐;这个资料来源于1987年写的一本书;2012年,它很有可能不适用于基于ARM的android设备。
for (int i = 0; i < 10000; i++)
  a[i] = b[i] + c[i]



mov r0,#0x2700
orr r0,#0x0010
top:
ldr r1,[r9],#4
ldr r2,[r10],#4
add r1,r1,r2
str r1,[r8],#4
subs r0,#1
bne top
void test() {
        register int i asm("r0");
        register int *a asm("r8");
        register int *b asm("r9");
        register int *c asm("r10");

        for (i = 0; i < 10000; i++) {
                a[i] = b[i] + c[i];
        }
}
arm-linux-androideabi-gcc -O0 -S test.c
<snipped>
.L3:
        mov     r2, r8
        mov     r3, r0
        mov     r3, r3, asl #2
        add     r3, r2, r3
        mov     r1, r9
        mov     r2, r0
        mov     r2, r2, asl #2
        add     r2, r1, r2
        ldr     r1, [r2, #0]
        mov     ip, sl
        mov     r2, r0
        mov     r2, r2, asl #2
        add     r2, ip, r2
        ldr     r2, [r2, #0]
        add     r2, r1, r2
        str     r2, [r3, #0]
        mov     r3, r0
        add     r3, r3, #1
        mov     r0, r3
.L2:
        mov     r2, r0
        ldr     r3, .L5
        cmp     r2, r3
        ble     .L3
        sub     sp, fp, #12
        ldmfd   sp!, {r8, r9, sl, fp}
        bx      lr
<snipped>
mov r11,#0x2700
orr r11,#0x0010
top:
ldmia r9!, {r0-r3}
ldmia r10!, {r4-r7}
add r0,r0,r4
add r1,r1,r5
add r2,r2,r6
add r3,r3,r7
stmia r8!, {r0-r3}
subs r11,#4
bne top