您尚未登录。

楼主 #1 2021-05-19 15:13:06

奔跑的孩子
会员
注册时间: 2021-01-28
已发帖子: 51
积分: 31.5

请教大家一个问题,thumb状态下,每一条指令都是16bit长度吗?

如题

离线

楼主 #2 2021-05-19 15:16:52

奔跑的孩子
会员
注册时间: 2021-01-28
已发帖子: 51
积分: 31.5

Re: 请教大家一个问题,thumb状态下,每一条指令都是16bit长度吗?

2021-05-19_151544.png

这个是怎么回事呢?

离线

楼主 #4 2021-05-19 15:24:18

奔跑的孩子
会员
注册时间: 2021-01-28
已发帖子: 51
积分: 31.5

Re: 请教大家一个问题,thumb状态下,每一条指令都是16bit长度吗?

aozima 说:

Thumb-2 多数16位,部分32位,自动变长。

怎么确定是 thumb,还是thumb-2呢?

离线

楼主 #6 2021-05-19 15:26:30

奔跑的孩子
会员
注册时间: 2021-01-28
已发帖子: 51
积分: 31.5

Re: 请教大家一个问题,thumb状态下,每一条指令都是16bit长度吗?

thumb指令,相比较与arm代码,储存器的功耗也较低。

thumb指令,基本都是无条件的,一共有18条基本指令,全部指令都是16bit。

Thumb-2指令,由16bit、32bit的指令混合组成,一共有16条基本指令,

搜了一下, 确实如此, 可是我的 gcc 命令行没有指定 thumb-2, 而是:

$(ARMGNU)-gcc -c $(COPS) -mthumb notmain.c -o notmain.o

离线

楼主 #8 2021-05-19 17:30:41

奔跑的孩子
会员
注册时间: 2021-01-28
已发帖子: 51
积分: 31.5

Re: 请教大家一个问题,thumb状态下,每一条指令都是16bit长度吗?

aozima 说:

我记得这里的BL看起好像是32位,实际上还是16位,但自动粘在一起了。

我看左边那个地址, bl应该是 4字节

离线

楼主 #10 2021-05-19 20:39:31

奔跑的孩子
会员
注册时间: 2021-01-28
已发帖子: 51
积分: 31.5

Re: 请教大家一个问题,thumb状态下,每一条指令都是16bit长度吗?

感谢大佬解惑,虽然还是一知半解,容我去给IQ充值再来提问。

离线

楼主 #11 2021-05-20 10:25:03

奔跑的孩子
会员
注册时间: 2021-01-28
已发帖子: 51
积分: 31.5

Re: 请教大家一个问题,thumb状态下,每一条指令都是16bit长度吗?

strap.s

.arm
_reset:
        ldr r0, =0x101f1000 //UART0发送寄存器地址
        ldr r1, =0x31       //输出1
        str     r1, [r0]
        ldr r0, =_thum_mode + 1
        bx r0

.thumb
_thum_mode:
        ldr r1, =0x32       //输出2
        str     r1, [r0]


        ldr r1, =0x33       //输出3
        str     r1, [r0]

@aozima 再请教大佬一个问题,为什么这个代码只能输出 1呢, 不能输出 2, 3

$ arm-linux-gnueabi-objdump -D strap.o

strap.o:     file format elf32-littlearm


Disassembly of section .text:

00000000 <_reset>:
   0:   e59f0014        ldr     r0, [pc, #20]   ; 1c <_thum_mode+0x8>
   4:   e3a01031        mov     r1, #49 ; 0x31
   8:   e5801000        str     r1, [r0]
   c:   e59f000c        ldr     r0, [pc, #12]   ; 20 <_thum_mode+0xc>
  10:   e12fff10        bx      r0

00000014 <_thum_mode>:
  14:   4903            ldr     r1, [pc, #12]   ; (24 <_thum_mode+0x10>)
  16:   6001            str     r1, [r0, #0]
  18:   4903            ldr     r1, [pc, #12]   ; (28 <_thum_mode+0x14>)
  1a:   6001            str     r1, [r0, #0]
  1c:   101f1000        andsne  r1, pc, r0
  20:   00000015        andeq   r0, r0, r5, lsl r0
  24:   00000032        andeq   r0, r0, r2, lsr r0
  28:   00000033        andeq   r0, r0, r3, lsr r0

Disassembly of section .ARM.attributes:

00000000 <.ARM.attributes>:
   0:   00001941        andeq   r1, r0, r1, asr #18
   4:   61656100        cmnvs   r5, r0, lsl #2
   8:   01006962        tsteq   r0, r2, ror #18
   c:   0000000f        andeq   r0, r0, pc
  10:   00543505        subseq  r3, r4, r5, lsl #10
  14:   01080306        tsteq   r8, r6, lsl #6
  18:   Address 0x0000000000000018 is out of bounds.

我照着书本写的, 基于arm926, 明明切换到了thumb模式。

离线

楼主 #13 2021-05-21 09:26:05

奔跑的孩子
会员
注册时间: 2021-01-28
已发帖子: 51
积分: 31.5

Re: 请教大家一个问题,thumb状态下,每一条指令都是16bit长度吗?

@aozima 感谢大佬,我再学习学习。

离线

楼主 #14 2021-05-24 09:15:56

奔跑的孩子
会员
注册时间: 2021-01-28
已发帖子: 51
积分: 31.5

Re: 请教大家一个问题,thumb状态下,每一条指令都是16bit长度吗?

.arm
_reset:
        ldr r0, =0x101f1000 //UART0发送寄存器地址
        ldr r1, =0x31       //输出1
        str     r1, [r0]
//      ldr r0, =_thumb_mode + 1
        adr r0, _thumb_mode + 1
        bx r0

.thumb
_thumb_mode:
        ldr r0, =0x101f1000 //UART0发送寄存器地址
        ldr r1, =0x32       //输出2
        str     r1, [r0]

        ldr r1, =0x33       //输出3
        str     r1, [r0]

这样可以输出 123 了,  前面没有初始化 r0 寄存器.

再加上
        ldr r0, =_thumb_mode + 1
替换
        adr r0, _thumb_mode + 1

$ qemu-system-arm -M versatilepb -m 128M -nographic -kernel notmain.bin
123

请问@aozima老大,为什么ldr指令不可以呢?

离线

楼主 #15 2021-05-24 12:15:45

奔跑的孩子
会员
注册时间: 2021-01-28
已发帖子: 51
积分: 31.5

Re: 请教大家一个问题,thumb状态下,每一条指令都是16bit长度吗?

这个代码不行:

.arm
_arm_mode:
        ldr r0, =0x101f1000 //UART0发送寄存器地址
        ldr r1, =0x31       //输出1
        str     r1, [r0]
        ldr r6, =_thumb_mode + 1
        add r6, #1
//      adr r6, _thumb_mode + 1
        bx r6

.thumb
_thumb_mode:
        ldr r0, =0x101f1000 //UART0发送寄存器地址
        ldr r1, =0x32       //输出2
        str     r1, [r0]


        ldr r1, =0x33       //输出3
        str     r1, [r0]

        ldr r1, =0x34       //输出4
        str     r1, [r0]

_loop:
        b _loop            //死循环


        bx lr           //跳回去

生成的代码:

$ arm-linux-gnueabi-objdump -D strap.o

strap.o:     file format elf32-littlearm


Disassembly of section .text:

00000000 <_arm_mode>:
   0:   e59f0024        ldr     r0, [pc, #36]   ; 2c <_loop+0x6>
   4:   e3a01031        mov     r1, #49 ; 0x31
   8:   e5801000        str     r1, [r0]
   c:   e59f601c        ldr     r6, [pc, #28]   ; 30 <_loop+0xa>
  10:   e2866001        add     r6, r6, #1
  14:   e12fff16        bx      r6

00000018 <_thumb_mode>:
  18:   4804            ldr     r0, [pc, #16]   ; (2c <_loop+0x6>)
  1a:   4906            ldr     r1, [pc, #24]   ; (34 <_loop+0xe>)
  1c:   6001            str     r1, [r0, #0]
  1e:   4906            ldr     r1, [pc, #24]   ; (38 <_loop+0x12>)
  20:   6001            str     r1, [r0, #0]
  22:   4906            ldr     r1, [pc, #24]   ; (3c <_loop+0x16>)
  24:   6001            str     r1, [r0, #0]

00000026 <_loop>:
  26:   e7fe            b.n     26 <_loop>
  28:   4770            bx      lr
  2a:   10000000        andne   r0, r0, r0
  2e:   0019101f        andseq  r1, r9, pc, lsl r0
  32:   00320000        eorseq  r0, r2, r0
  36:   00330000        eorseq  r0, r3, r0
  3a:   00340000        eorseq  r0, r4, r0
        ...





这个是可以的:

.arm
_arm_mode:
        ldr r0, =0x101f1000 //UART0发送寄存器地址
        ldr r1, =0x31       //输出1
        str     r1, [r0]
//      ldr r6, =_thumb_mode + 1
//      add r6, #1
        adr r6, _thumb_mode + 1
        bx r6

.thumb
_thumb_mode:
        ldr r0, =0x101f1000 //UART0发送寄存器地址
        ldr r1, =0x32       //输出2
        str     r1, [r0]


        ldr r1, =0x33       //输出3
        str     r1, [r0]

        ldr r1, =0x34       //输出4
        str     r1, [r0]

_loop:
        b _loop            //死循环


        bx lr           //跳回去

生成的代码:

$ arm-linux-gnueabi-objdump -D strap.o

strap.o:     file format elf32-littlearm


Disassembly of section .text:

00000000 <_arm_mode>:
   0:   e59f0020        ldr     r0, [pc, #32]   ; 28 <_loop+0x6>
   4:   e3a01031        mov     r1, #49 ; 0x31
   8:   e5801000        str     r1, [r0]
   c:   e28f6001        add     r6, pc, #1
  10:   e12fff16        bx      r6

00000014 <_thumb_mode>:
  14:   4804            ldr     r0, [pc, #16]   ; (28 <_loop+0x6>)
  16:   4905            ldr     r1, [pc, #20]   ; (2c <_loop+0xa>)
  18:   6001            str     r1, [r0, #0]
  1a:   4905            ldr     r1, [pc, #20]   ; (30 <_loop+0xe>)
  1c:   6001            str     r1, [r0, #0]
  1e:   4905            ldr     r1, [pc, #20]   ; (34 <_loop+0x12>)
  20:   6001            str     r1, [r0, #0]

00000022 <_loop>:
  22:   e7fe            b.n     22 <_loop>
  24:   4770            bx      lr
  26:   10000000        andne   r0, r0, r0
  2a:   0032101f        eorseq  r1, r2, pc, lsl r0
  2e:   00330000        eorseq  r0, r3, r0
  32:   00340000        eorseq  r0, r4, r0

难道是ldr伪指令不能生成跳转到thumb?

离线

楼主 #17 2021-05-24 23:17:51

奔跑的孩子
会员
注册时间: 2021-01-28
已发帖子: 51
积分: 31.5

Re: 请教大家一个问题,thumb状态下,每一条指令都是16bit长度吗?

QQ截图20210524231541.png

QQ截图20210524231645.png

同样都是 0x15 给 R6, 为什么 上面的不行呢?

离线

楼主 #18 2021-05-25 10:19:20

奔跑的孩子
会员
注册时间: 2021-01-28
已发帖子: 51
积分: 31.5

Re: 请教大家一个问题,thumb状态下,每一条指令都是16bit长度吗?

2021-05-25_101634.png


感觉应该是qemu虚拟机的bug, 因为我用 MDK + GCC工具链 + 模拟调试, 发现编译出来的代码并无二致。

寄存器值一模一样。

离线

页脚

工信部备案:粤ICP备20025096号 Powered by FluxBB

感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信(wechat): whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn