【问题标题】:Want to read string and output same string in assembly想在汇编中读取字符串并输出相同的字符串
【发布时间】:2014-10-29 19:09:05
【问题描述】:

我知道内存中的字符串不像存储数字或字符那么容易。我正在尝试使用 .word 指令存储字符串,我知道这可能是错误的。我不确定如何将字符串存储在内存中然后输出。是将字符串存储为一堆 %c 然后一个一个地输出每个字符的唯一选择是什么?我正在尝试看看是否有更简单的方法可以做到这一点。我尝试了 .string 指令而不是 .word ,但这被认为是有效的指令。

.data

.balign 4

input_name: .asciz "enter name: "

.balign 4

output_name: .asciz "name entered : %s\n"

.balign 4

scan_pattern: .asciz "%s"

.balign 4

name_read: .word 0

.balign 4

return: .word 0

.global main

main:

        ldr r1, =return       

        str lr, [r1]


        ldr r0, =input_name

        bl printf


        ldr r0, =scan_pattern

        ldr r1, = name_read

        bl scanf


        ldr 0, =ouput_name

        ldr r1, =name_read

        ldr r1, [r1]

        bl printf


        ldr lr, =return

        ldr lr, [lr]

        bx lr

【问题讨论】:

  • 我不太确定你指的是什么字符串,也许是 scanf 的输出?首先有一堆其他的 cmets:有一堆明显的错字(例如 ldr 0,=output_name)可能只是复制/粘贴的东西,因为我看不出它是如何构建的。 C 方法需要一个堆栈——也许它已经在某个地方设置好了。代码在 .data 部分,通常进入 .text。不是像那样操纵 lr,而是 (a) 在最后调用 'b main' 以返回开始。 (b) 将 lr 压入堆栈并弹出到 pc 中。
  • 接下来 - 分配空间。您可以使用 .space 指令。假设您想为您的字符串分配 64 个字节。 mystring: .space 64 将 scan_pattern 分配给 r0 并将 myspace 分配给 r1 以调用 scanf 并再次调用以下 printf。这是gas ARM directives的备忘单@

标签: gcc assembly arm


【解决方案1】:

解决此类问题的一般方法是“询问编译器”。你知道,你想要做的是:

#include <stdio.h>

char str[1024];

int
main (void)
{
  scanf("%s", str);
  printf ("%s\n", str);
  return 0;
}

现在使用任何交叉编译器。不知道你的汇编语法,这很奇怪,但问题被标记为“gcc”,所以对于这个例子,让我们以Linaro GCC

gcc-linaro-2014.01/bin/arm-linux-gnueabihf-gcc -S -O2 test.c

输出汇编是:

    .thumb
    .file   "test.c"
    .section        .text.startup,"ax",%progbits
    .align  2
    .global main
    .thumb
    .thumb_func
    .type   main, %function
main:
    @ args = 0, pretend = 0, frame = 0
    @ frame_needed = 0, uses_anonymous_args = 0
    push    {r4, lr}
    movw    r4, #:lower16:str
    movt    r4, #:upper16:str
    movw    r0, #:lower16:.LC0
    mov     r1, r4
    movt    r0, #:upper16:.LC0
    bl      __isoc99_scanf
    mov     r0, r4
    bl      puts
    movs    r0, #0
    pop     {r4, pc}
    .size   main, .-main
    .comm   str,1024,4
    .section        .rodata.str1.4,"aMS",%progbits,1
    .align  2
.LC0:
    .ascii  "%s\000"
    .ident  "GCC: (crosstool-NG linaro-1.13.1-4.8-2014.01 - Linaro GCC 2013.11) 4.8.3 20140106 (prerelease)"
    .section        .note.GNU-stack,"",%progbits

我认为一切都很清楚 -- 你可以看到 .comm 用于字符串缓冲区的指令和.ascii 用于 printf 模式。

在你的编译器上,一切都可能改变,但我概述了方法。先看编译器生成的东西,接下来自己写汇编。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-18
    • 1970-01-01
    相关资源
    最近更新 更多