I am trying to learn the ARM assembly, and in my computer-generated .s file there are several lines that confuse me, first of all, this block:
.L6: .word .LC0-(.LPIC8+4) .word .LC1-(.LPIC10+4 .word .LC0-(.LPIC11+4)
and how it relates to this block:
.LCFI0: ldr r3, .L6 .LPIC8: add r3, pc
My best guess is telling me that this loads the memory address (beginning) of my ascii string into r3, but I'm confused how this happens exactly .. LC0 - (. LPIC8 + 4) - this is the difference between where add r3, pc is called and where is the line. Adding pc to this difference should end in a line, but why not just call
ldr r3, .LC0
instead of these things .word and this inconvenient pair and ldr / add? Is this the only or best way for the compiler to handle this, or is it just the result of some general algorithm that the compiler uses to create such code?
In addition, what is
@ sp needed for prologue
It sounds like a reminder that the compiler adds stack pointer processing to the prolog. But I feel that this was about to happen, and that not where the prologue is ..
Below is most of the build code with my reliable correct comments (there are some debugging materials at the end, but it is too long to include.
Any help that anyone can provide will be appreciated!
.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
and here is the c code:
#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; }