该组件code使什么 [英] This assembly code makes nothing

查看:311
本文介绍了该组件code使什么的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在C文件,它是这样工作的:

 的#define V2 0x560000a0
    INT主要(无效)
    {
        长整型V1;
        V1 = ioread32(V2);
        返回0;
    }

和我已经提取这部分把它写在装配:

  INT的main()
{
    EXTERN V1,V2;
    V1 = ioread32(V2);
    返回0;
}

我想写V2在V1使用汇编code为ARM版本的值。使用

  ARM-Linux的gnueabi-GCC -S -march = ARM版本assembly_file.c

我得到这个code:

  .arch的ARMv4
.eabi_attribute 27日,3
.fpu的VFPv3-D16
.eabi_attribute 20,1
.eabi_attribute 21 1
.eabi_attribute 23,3
.eabi_attribute 24,1
.eabi_attribute 25,1
.eabi_attribute 26,2
.eabi_attribute 30,6
.eabi_attribute 34,0
.eabi_attribute 18,4
.filetxind-rsi.c
。文本
.align伪2
。全球主要
.TYPE为主,功能%主要:
@功能支持的互通。
@ ARGS = 0,pretend = 0,帧= 0
@ frame_needed = 1,uses_anonymous_args = 0
STMFD SP !, {FP,LR}
添加FP,SP,#4
LDR R3,.L2
LDR R3,[R3,#0]
MOV R0,R3
BL ioread32
MOV R2,R0
LDR R3,.L2 + 4
STR R2,[R3,#0]
MOV R3,#0
MOV R0,R3
子SP,FP,#4
LDMFD SP !, {FP,LR}
BX LR.L3:
.align伪2.L2:
.word V1
.word V2
.size为主,。,主
.identGCC:(Ubuntu的/ Linaro的4.6.3-1ubuntu5)4.6.3
.section伪.note.GNU栈,,%PROGBITS

我用code把它放回去C文件里面是这样的:

  ASM挥发性(
    STMFD SP !, {FP,LR} \\ n
    添加FP,SP,#4 \\ n
    LDR R3,= V \\ n
    LDR R3,[R3,#0] \\ n
    MOV R0,R2 \\ n
    LDR R3,= V \\ n
    海峡R2,[R3,#0] \\ n
    分SP,FP,#4 \\ n
    LDMFD SP !, {FP,LR} \\ n
    BX LR
);

在code没有做任何事情。

在事实上,它停止目标工作。
任何人是否知道为什么?

编辑:
看完你的答案后,我有一个问题:
我将如何把一个寄存器中的恒定值?在C code会是这样:

 的#define V2 0x560000a0
INT主要(无效)
{
    长整型值= 0x0000ffff;
    长整型V1;
    V1 = ioread32(V2);
    iowrite32(V2,值);
    返回0;
}

我试过这样:

  ASM挥发性(MOV R3,#VALUE);

和我得到一个汇编程序的消息:价值符号在不同的部分;
我也试过

  ASM挥发性(MOV R3,#0x0000ffff);

和汇编的信息是:
无效的常数(FFFF)修正后的。而看完这个:无效不断修正后
我不知道我怎样才能把这些值转换成R3,因为它似乎与mov.I'm使用ARM版本,我不能做到这一点,没有的ARMv7。在链接提出的这个解决方案,不为我工作:

  ASM挥发性(LDR R3,=#0000FFFF \\ n);


解决方案

有您的code没有问题,BX LR是终止为主,没有出现问题的正确方法。您code是最容易崩溃是由于您正在访问的地址,它可能不是你被允许访问的地址...

 的#define V2 0x560000a0
    INT主要(无效)
    {
        长整型V1;
        V1 = ioread32(V2);
        返回0;
    }

如果您优化对C编译步骤中,您可以看到一个更清洁,更简单的版本

  00000000<主计算值:
   0:e92d4008推{R3,LR}
   4:e59f0008 LDR R0,[PC,#8]; 14 lt;主+ 0×14>
   8:ebfffffe BL 0℃; ioread32>
   C:e3a00000 MOV R0,#0
  10:e8bd8008流行{R3,PC}
  14:560000a0 strpl R0,[R0],-R 0,LSR#1

这是不是很难在ASM来实现。

  .globl主
主要:
    推{R3,LR}
    LDR R0,= 0x560000A0
    BL ioread32
    MOV R0,#0
    POP {R3,PC}

组装和拆卸

  00000000<主计算值:
   0:e92d4008推{R3,LR}
   4:e59f0008 LDR R0,[PC,#8]; 14 lt;主+ 0×14>
   8:ebfffffe BL 0℃; ioread32>
   C:e3a00000 MOV R0,#0
  10:e8bd8008流行{R3,PC}
  14:560000a0 strpl R0,[R0],-R 0,LSR#1

您已经简化了code到V1变成死code点,但功能调用不能被优化了,因此,返回被丢弃。

如果您不使用主,但创建一个单独的函数,返回

 的#define V2 0x560000a0
    长整型乐趣(无效)
    {
        长整型V1;
        V1 = ioread32(V2);
        返回V1;
    }

... ...该死的尾巴优化:

  00000000<有趣的计算值:
   0:e59f0000 LDR R0,[PC]; 8示乐趣+ 0x8中>
   4:eafffffe B 0,&所述; ioread32>
   8:560000a0 strpl R0,[R0],-R 0,LSR#1

哦。你是在正确的道路上,看看有什么C编译器生成然后模仿或修改。我怀疑这是你ioread这就是问题所在,而不是外部结构(为什么你在做一个64位的事情有32位读,也许这就是问题长期是最有可能会被实现为64位)。

I'm working in a C file, which is something like this:

    #define v2      0x560000a0
    int main(void)
    {
        long int v1;
        v1 = ioread32(v2);
        return 0;
    }

and I've extracted this part to write it in assembly:

int main ()
{
    extern v1,v2;
    v1=ioread32(v2);
    return 0;
}

I'm trying to write the value of v2 in v1 using assembly code for armv4. Using

arm-linux-gnueabi-gcc -S -march=armv4 assembly_file.c

I get this code:

.arch armv4
.eabi_attribute 27, 3
.fpu vfpv3-d16
.eabi_attribute 20, 1
.eabi_attribute 21, 1
.eabi_attribute 23, 3
.eabi_attribute 24, 1
.eabi_attribute 25, 1
.eabi_attribute 26, 2
.eabi_attribute 30, 6
.eabi_attribute 34, 0
.eabi_attribute 18, 4
.file   "txind-rsi.c"
.text
.align  2
.global main
.type   main, %function

main:
@ Function supports interworking.
@ args = 0, pretend = 0, frame = 0
@ frame_needed = 1, uses_anonymous_args = 0
stmfd   sp!, {fp, lr}
add fp, sp, #4
ldr r3, .L2
ldr r3, [r3, #0]
mov r0, r3
bl  ioread32
mov r2, r0
ldr r3, .L2+4
str r2, [r3, #0]
mov r3, #0
mov r0, r3
sub sp, fp, #4
ldmfd   sp!, {fp, lr}
bx  lr

.L3:
.align  2

.L2:
.word   v1
.word   v2
.size   main, .-main
.ident  "GCC: (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3"
.section    .note.GNU-stack,"",%progbits

I use that code to put it back inside the C file this way:

asm volatile(
    "stmfd  sp!, {fp, lr}\n"
    "add    fp, sp, #4\n"
    "ldr    r3, =v1\n"
    "ldr    r3, [r3, #0]\n"
    "mov    r0, r2\n"
    "ldr    r3, =v2\n"
    "str    r2, [r3, #0]\n"
    "sub    sp, fp, #4\n"
    "ldmfd  sp!, {fp, lr}\n"
    "bx lr"
);

The code doesn't do anything.

In fact, it stops the target working. Does anyones know why?

EDITED: After reading your answers I have another question: How would I put a constant value in a register?. The code in C would be this:

#define v2      0x560000a0
int main(void)
{
    long int value = 0x0000ffff;
    long int v1;
    v1 = ioread32(v2);
    iowrite32(v2,value);
    return 0;
}

I've tried this:

asm volatile("mov r3, #value");

and I get an assembler message: "value symbol is in a different section"; I've also tried

asm volatile("mov r3, #0x0000ffff);

and the assembler message is: "invalid constant(ffff) after fixup". And after reading this: Invalid constant after fixup? I don't know how I can put that value into r3, as it seems I can't do it with mov.I'm using armv4, not armv7. And this solution proposed in the link, doesn't work for me:

asm volatile("ldr   r3, =#0000ffff\n");

解决方案

There are no problems with your code, bx lr is the proper way to terminate main, no issue there. Your code is most likely crashing due to the address you are accessing, it is probably not an address you are allowed to access...

#define v2      0x560000a0
    int main(void)
    {
        long int v1;
        v1 = ioread32(v2);
        return 0;
    }

if you optimize on the C compile step you can see a cleaner, simpler version

00000000 <main>:
   0:   e92d4008    push    {r3, lr}
   4:   e59f0008    ldr r0, [pc, #8]    ; 14 <main+0x14>
   8:   ebfffffe    bl  0 <ioread32>
   c:   e3a00000    mov r0, #0
  10:   e8bd8008    pop {r3, pc}
  14:   560000a0    strpl   r0, [r0], -r0, lsr #1

which is not hard to implement in asm.

.globl main
main:
    push {r3,lr}
    ldr r0,=0x560000A0
    bl ioread32
    mov r0,#0
    pop {r3,pc}

assembled and disassembled

00000000 <main>:
   0:   e92d4008    push    {r3, lr}
   4:   e59f0008    ldr r0, [pc, #8]    ; 14 <main+0x14>
   8:   ebfffffe    bl  0 <ioread32>
   c:   e3a00000    mov r0, #0
  10:   e8bd8008    pop {r3, pc}
  14:   560000a0    strpl   r0, [r0], -r0, lsr #1

you had simplified the code to the point that v1 becomes dead code, but the function call cannot be optimized out, so the return is discarded.

if you dont use main but create a separate function that returns

#define v2      0x560000a0
    long int fun(void)
    {
        long int v1;
        v1 = ioread32(v2);
        return v1;
    }

...damn...tail optimization:

00000000 <fun>:
   0:   e59f0000    ldr r0, [pc]    ; 8 <fun+0x8>
   4:   eafffffe    b   0 <ioread32>
   8:   560000a0    strpl   r0, [r0], -r0, lsr #1

Oh well. You are on the right path, see what the C compiler generates then mimic or modify that. I suspect it is your ioread that is the problem and not the outer structure (why are you doing a 64 bit thing with a 32 bit read, maybe that is the problem long it is most likely going to be implemented as 64 bit).

这篇关于该组件code使什么的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆