C字符串没有在循环中正确迭代

时间:2016-11-18 15:44:17

标签: c arrays arm embedded beagleboneblack

我正在尝试通过Beaglebone Black的UART0打印字符串。引导程序初始化UART0,我只需要写字符。我做了一个简单的功能

/sub.domain.com/cache/400x400/image.jpg

从启动代码调用以下函数我只是在此函数中打印字符。

void uart_put(unsigned char c)
{
    while((UART0->LSR_r & 32) == 0);
    UART0->THR = c;     
}

该函数工作正常,因为正确打印了字符数组和整数,但字符串未按原样打印。 enter image description here

1 个答案:

答案 0 :(得分:7)

在链接描述文件中,更改:

. = 0x402F0400;

为:

. = 0x80000000;

根据memory map for the AM335X ARM processor0x402F0400是核心SRAM,而0x8000000是DDR2内存。根据TFTP启动输出的屏幕截图,您将在0x80000000加载应用程序,但您的链接描述文件已配置为引用0x402F04000处的内存。

反汇编使用原始链接描述文件构建的原始二进制文件download.bin会产生:

% arm-none-eabi-objdump -D -b binary -marm download.bin
download.bin:     file format binary

Disassembly of section .data:

00000000 <.data>:
    0:   e51fd000        ldr     sp, [pc, #-0]   ; 0x8
    4:   eb00000e        bl      0x44
    8:   402f1638        eormi   r1, pc, r8, lsr r6      ; <UNPREDICTABLE>
    c:   e52db004        push    {fp}            ; (str fp, [sp, #-4]!)
    [removed several lines of text]
    4c:   e24dd030        sub     sp, sp, #48     ; 0x30
    50:   e300262c        movw    r2, #1580       ; 0x62c
    54:   e344202f        movt    r2, #16431      ; 0x402f
    [remainder of dump removed]

将字符串从内存复制到局部变量中。请注意,字符串副本的地址为0x402f062cmovwmovt命令将地址加载到寄存器中。快速扫描省略的代码不会显示任何其他访问内存的尝试。

我无法访问Beaglebone Black,因此我无法对此进行测试。它确实解释了观察到的行为。由于程序正在从未初始化的SRAM复制字符串,因此无法保证将显示的内容。由于没有其他尝试访问程序中的内存,这是唯一的问题。

更改链接描述文件并重建结果略有不同download.bin。原始链接描述文件生成的反汇编download.bin与我建议的更改之间的区别是:

10c10
<    8: 402f1638        eormi   r1, pc, r8, lsr r6      ; <UNPREDICTABLE>
---
>    8: 80001238        andhi   r1, r0, r8, lsr r2
28,29c28,29
<   50: e300262c        movw    r2, #1580       ; 0x62c
<   54: e344202f        movt    r2, #16431      ; 0x402f
---
>   50: e300222c        movw    r2, #556        ; 0x22c
>   54: e3482000        movt    r2, #32768      ; 0x8000

您可以清楚地看到复制字符串的新地址参考。不幸的是,我不确定其他变化是什么,以及这种变化是否会引起任何问题。

为了验证字符串是否为0x8000022c,我们可以使用xxd来转储download.bin。输出是:

% xxd download.bin
0000000: 00d0 1fe5 0e00 00eb 3816 2f40 04b0 2de5  ........8./@..-.
0000010: 00b0 8de2 14d0 4de2 0030 a0e1 0d30 4be5  ......M..0...0K.
[... omitted lots of lines ...]
0000220: 0500 53e3 cdff ffda feff ffea 4865 6c6c  ..S.........Hell
0000230: 6f00 0000                                o...

字符Hello0x22c处可见。在0x80000000加载时,复制字符串的地址似乎是正确的。