ARM的汇编控制如下:

  • IF、ELSE及ENDIF
  • WHILE及WEND
  • MACRO及WEND
  • MEXIT

 

32位示例

完成1+2+…+22。

.text.global mainmain:    mov r1, #0       /* r1 ← 0 */    mov r2, #1       /* r2 ← 1 */loop:     cmp r2, #22      /* compare r2 and 22 */    bgt end          /* branch if r2 > 22 to end */    add r1, r1, r2   /* r1 ← r1 + r2 */    add r2, r2, #1   /* r2 ← r2 + 1 */    b loopend:    mov r0, r1       /* r0 ← r1 */    bx lr复制代码

as -g -o loop01.o loop01.s

gcc -o loop01 loop01.o

执行后通过echo $?获得结果为253。

修改代码中的#22为#100,就可以得到1+2+…+100=5050。

但是不能通过$?来获得结果,应为Linux中错误码的返回是8位的,5050超过8位了。

5050的二进制是1001110111010,后面八位是10111010,也就是186,改成#100后,通过echo $?返回的事186,但是通过gdb调试可以去查看r1其真实为5050。

64位示例

.arch armv8-a.global _start.text_start:    mov x1, #0       /* r1 ← 0 */    mov x2, #1       /* r2 ← 1 */loop:     cmp x2, #22      /* compare r2 and 22 */    bgt end          /* branch if r2 > 22 to end */    add x1, x1, x2   /* r1 ← r1 + r2 */    add x2, x2, #1   /* r2 ← r2 + 1 */    b loopend:    mov x0, x1       /* r0 ← r1 */    mov x8, 93svc 0复制代码

as -g -o loop64.o loop64.s

ld -o loop64 loop64.o

执行后如下:

echo $?

253

 

32示例冰雹猜想

Collatz猜想:即一个正整数x,如果是奇数就乘以3再加1,如果是偶数就析出偶数因数2ⁿ,这样经过若干个次数,最终回到1。

无论N是怎样一个数字,最终都回到谷底1。准确地说,是无法逃出落入底部的4-2-1循环。

.text.global mainmain:    mov r1, #123           /* r1 ← 123 */    mov r2, #0             /* r2 ← 0 */loop:    cmp r1, #1             /* compare r1 and 1 */    beq end                /* branch to end if r1 == 1 */     and r3, r1, #1         /* r3 ← r1 & 1 */    cmp r3, #0             /* compare r3 and 0 */    bne odd                /* branch to odd if r3 != 0 */even:    mov r1, r1, ASR #1     /* r1 ← (r1 >> 1) */    b end_loopodd:    add r1, r1, r1, LSL #1 /* r1 ← r1 + (r1 << 1) */    add r1, r1, #1         /* r1 ← r1 + 1 */ end_loop:    add r2, r2, #1         /* r2 ← r2 + 1 */    b loop                 /* branch to loop */ end:    mov r0, r2    bx lr复制代码

as -g -o collatz.o collatz.s

gcc -o collatz collatz.o

执行后如下:

./collatz

echo $?

46

表示经过了46次变化。

入参为123,经过的步骤为:

[123, 370, 185, 556, 278, 139, 418, 209, 628, 314, 157, 472, 236, 118, 59, 178, 89, 268, 134, 67, 202, 101, 304, 152, 76, 38, 19, 58, 29, 88, 44, 22, 11, 34, 17, 52, 26, 13, 40, 20, 10, 5, 16, 8, 4, 2, 1]

 

C代码

#include <stdio.h>#include <stdint.h>int main (){    unsigned long long i,n,x = 0;                       //i是不断变高的数    int count = 0;    int max = 0;    n = 123;    i = n;    while(i!=1)    {        if(i %2 == 1)                           //如果是个奇数        {            i=3*i+1;        }        else if(i %2 == 0)                      //如果是个偶数        {            i=i/2;        }        count++;                //累加转换次数    }    printf("当前:%llu[变换次数%d]\n",n, count);    return 0;}复制代码

gcc -o collatz-c collatz.c

结果也是46次变化。

 

64位示例冰雹猜想

.arch armv8-a.global _start.text_start:    mov x1, #123           /* r1 ← 123 */    mov x2, #0             /* r2 ← 0 */loop:    cmp x1, #1             /* compare r1 and 1 */    beq end                /* branch to end if r1 == 1 */     and x3, x1, #1         /* r3 ← r1 & 1 */    cmp x3, #0             /* compare r3 and 0 */    bne odd                /* branch to odd if r3 != 0 */even:    mov x1, x1, ASR #1     /* r1 ← (r1 >> 1) */    b end_loopodd:    add x1, x1, x1, LSL #1 /* r1 ← r1 + (r1 << 1) */    add x1, x1, #1         /* r1 ← r1 + 1 */ end_loop:    add x2, x2, #1         /* r2 ← r2 + 1 */    b loop                 /* branch to loop */end:    mov x0,x2    mov x8, 93svc 0复制代码

as -g -o collatz64.o collatz64.s

ld -o collatz64 collatz64.o

执行后结果如下:

echo $?

46

从这里我们可以看到32位的ARM汇编切换到64位其实是比较简单的。需要注意的是寄存器的变化和退出的方式。


©著作权归作者所有:来自51CTO博客作者wx607823dfcf6a9的原创作品,如需转载,请注明出处,否则将追究法律责任

更多相关文章

  1. 实现文件上下文管理(__enter__和__exit__)
  2. 流程控制之if判断
  3. 给我1万字,也讲不清Java内存排查。1万不行来2万~.~
  4. 想把Java代码写的更漂亮么?了解一下Try吧
  5. 解析Java横死之谜,气定神闲看花开花落
  6. 将java进程转移到“解剖台”之前,法医都干了什么?
  7. 工作累了,用java写个游戏吧!开源一款游戏引擎
  8. 一些好用的Java小库儿
  9. 牛气的JavaScript,让雪花算法成为空气

随机推荐

  1. golang 是否需要orm
  2. golang获取当前时间是第几周
  3. golang如何利用多核
  4. golang 如何运行
  5. golang 如何优化
  6. golang 如何处理死锁
  7. golang中如何比较字符串是否相等
  8. golang如何判断channel已经close
  9. golang 如何并发
  10. golang如何调试