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 ARM组件加载ASCII内存地址_Assembly_Arm_Ascii - Fatal编程技术网

Assembly ARM组件加载ASCII内存地址

Assembly ARM组件加载ASCII内存地址,assembly,arm,ascii,Assembly,Arm,Ascii,我正在尝试学习ARM组装,在我的计算机生成的.s文件中有几行让我感到困惑,主要是这一块: .L6: .word .LC0-(.LPIC8+4) .word .LC1-(.LPIC10+4 .word .LC0-(.LPIC11+4) .LCFI0: ldr r3, .L6 .LPIC8: add r3, pc 以及它与该区块的关系: .L6: .word .LC0-(.LPIC8+4) .word .LC1-(

我正在尝试学习ARM组装,在我的计算机生成的.s文件中有几行让我感到困惑,主要是这一块:

.L6:
   .word    .LC0-(.LPIC8+4)
   .word    .LC1-(.LPIC10+4
   .word    .LC0-(.LPIC11+4)
.LCFI0:
     ldr r3, .L6

.LPIC8:
     add r3, pc
以及它与该区块的关系:

.L6:
   .word    .LC0-(.LPIC8+4)
   .word    .LC1-(.LPIC10+4
   .word    .LC0-(.LPIC11+4)
.LCFI0:
     ldr r3, .L6

.LPIC8:
     add r3, pc
我的最佳猜测告诉我,这是将ascii字符串的内存地址(开头)加载到r3中,但我不清楚这到底是如何发生的。LC0-(.LPIC8+4)是调用add r3,pc的位置与字符串所在位置之间的差异。将pc添加到这个差异中应该会返回字符串,但是为什么不直接调用呢

ldr r3, .LC0
而不是这些。单词的东西和这个笨拙的ldr/添加对?这是编译器处理这一问题的唯一或最佳方法,还是仅仅是编译器用来生成类似代码的一些通用算法的结果

还有,什么是

    @ sp needed for prologue
这听起来像是提醒编译器将堆栈指针处理添加到序言中。但我觉得这应该已经发生了,而不是开场白

下面是我希望注释正确的大部分汇编代码(最后有一些调试内容,但太长了,无法包含在内)

任何人能提供的任何帮助都将不胜感激

    .arch armv5te
    .fpu softvfp
.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, 2
.eabi_attribute 18, 4
.code   16
.file   "helloneon.c"
.section    .debug_abbrev,"",%progbits
.Ldebug_abbrev0:
    .section    .debug_info,"",%progbits
.Ldebug_info0:
    .section    .debug_line,"",%progbits
.Ldebug_line0:
    .text
.Ltext0:
    .section    .text.main,"ax",%progbits
    .align  2
    .global main
    .code   16
    .thumb_func
    .type   main, %function
main:
    .fnstart
.LFB4:
    .file 1 "jni/helloneon.c"
    .loc 1 4 0
    .save   {r4, lr}
    push    {r4, lr}
.LCFI0:
    .loc 1 4 0
    ldr r3, .L6             ; r3 = char* hello, first position
.LPIC8:
    add r3, pc              ; pc = program counter, r3 += pc?
    .loc 1 3 0
    mov r1, r3              ; r1 = r3
    add r1, r1, #127        ; r1 += 127
.L2:
    .loc 1 10 0             ; r2 = holding an item in char* hello. r3 = pointer to location in hello
    ldrb    r2, [r3]        ; r2 = r3 load next char
    sub r2, r2, #32         ; r2 -=32 subtract 32 to char in register
    strb    r2, [r3]        ; r3 = r2 put uppercase char 
    add r3, r3, #1          ; r3 += 1
    .loc 1 8 0
    cmp r3, r1              ; compare r3, r1
    bne .L2                 ; if not equal, goto L2
    .loc 1 13 0
    ldr r0, .L6+4           ; r0 = 
    ldr r1, .L6+8           ; r1 = 
    .loc 1 16 0
    @ sp needed for prologue
    .loc 1 13 0
.LPIC10:
    add r0, pc              ; r0 += pc
.LPIC11:
    add r1, pc              ; r1 += pc
    bl  printf              ; goto printf
    .loc 1 16 0
    mov r0, #0              ; r0 = 0
    pop {r4, pc}            ; epilogue
.L7:
    .align  2
.L6:
    .word   .LC0-(.LPIC8+4)     ; 
    .word   .LC1-(.LPIC10+4)    ; 
    .word   .LC0-(.LPIC11+4)    ; 
.LFE4:
    .fnend
    .size   main, .-main
    .section    .rodata.str1.4,"aMS",%progbits,1
    .align  2
.LC0:
    .ascii  "helloworldthisismytestprogramtoconvertlowcharstobig"
    .ascii  "charsiamtestingneonandineedaninputofonehundredandtw"
    .ascii  "entyeightcharactersinleng\000"
.LC1:
    .ascii  "%s\000"
    .section    .debug_frame,"",%progbits
.Lframe0:
    .4byte  .LECIE0-.LSCIE0
.LSCIE0:
    .4byte  0xffffffff
    .byte   0x1
    .ascii  "\000"
    .uleb128 0x1
    .sleb128 -4
    .byte   0xe
    .byte   0xc
    .uleb128 0xd
    .uleb128 0x0
    .align  2
下面是c代码:

#include <stdio.h>

int main()
{
    char* hello = "helloworldthisismytestprogramtoconvertlowcharstobigcharsiamtestingneonandineedaninputofonehundredandtwentyeightcharactersinleng"; // len = 127 + \0
    int i, size = 127;

    for (i = 0; i < size; i++)
    {
        hello[i] -= 32;
    }

    printf("%s", hello);

    return 0;
}
#包括
int main()
{
char*hello=“helloworldthismytestprogramtoconvertlowcharstobigcharmsiamtestingneon和dineed,长度为100个和28个字符”;//len=127+\0
int i,大小=127;
对于(i=0;i
ldr r3、.L6
是一条伪指令。它实际转换为类似于
ldr r3、[pc,#offset]
,其中
offset
是ldr指令与其试图加载的值的位置之间的内存距离。 ARM处理器的固定宽度指令意味着您在LDR/STR指令中的偏移量上只需要花费这么多位,这反过来意味着通过PC相对加载加载的值必须存储在相当接近相应加载指令的位置

.LC0
.LPIC8
位于完全不同的部分,因此很可能超出PC相对负载的范围

一些ARM汇编程序提供了一个指令,可用于将文本的“池”分散到代码所在的同一部分。例如:

LDR r3,=.LC0   ; note the '='
....
.LTORG
在这样一个汇编程序中,会转换成这样的东西:

LDR r3,[pc,#offset_to_LC0Value]
....
LC0Value: .word .LC0


在问题中显示的汇编代码中,不只是加载是PC相关的;加载的值也是PC相关的。原因是获取位置无关的代码。如果加载并使用绝对地址,则代码将失败,除非它是从特定的虚拟地址执行的。访问所有rel通过与当前电脑相关的地址发送数据,您可以打破这种依赖关系。

将PIC作为独立于位置的代码读取。这样您就不需要提供固定地址。旧的指令是。pool,它可能仍然受支持,是我上次尝试的