【问题标题】:How to find the length of a string using ARM Assembly on a Raspberry Pi如何在 Raspberry Pi 上使用 ARM 程序集查找字符串的长度
【发布时间】:2014-03-05 05:41:41
【问题描述】:

我目前正在使用具有 ARM 架构的 RPI 学习汇编。我已经创建了下面的代码。但是,当我输入一个字符串(例如“hi”)时,会出现一些问题。 我没有收到正确的长度。示例:“Hi”-> 长度为 8(显然不正确)。 当输入大于 4 个字符时,我也会出现段错误。示例:“Hello”-> 长度为 8,然后是段错误。

我希望我做错了什么! :) 提前感谢您的帮助。

.data

/*Message1 */
.balign 4
message1: .asciz "Enter a string: "

/* Message 2 */
.balign 4
message2: .asciz "Your string has a length of %d\n"

/* Message 3 */
.balign 4
message3: .asciz "Your string is '%s'.\n"

/* format for scanf */
.balign 4
pattern: .asciz "%s"

/*Where we will store the length of the string */
.balign 4
strLen: .word 0

/*where scanf will store the string */
.balign 4
string: .asciz ""

/*Return value */
.balign 4
return: .word 0

/* Text Section */
.text

end:
        ldr lr, add_of_return /*load in the return address to lr */
        ldr lr, [lr] /* load the value at the address lr into lr */
        bx lr  /* branch exchange (basically end the program) */

add_of_return: .word return

calcStrLen:
        /*load in the first character to reg 2
          compare it to 0 and branch to label
          'done' if the two are the same */

        ldr r2, [r1]
        beq done

        /* increment the counter (r0) and the
           string pointer (r1) */
        add r0, r0, #1
        add r1, r1, #1

        /* store counter value into strLen */
           str r0, [r3]

        /* branch back to top of 'calcStrLen' */
           b calcStrLen

done:
        /* load the address of strLen to reg 1
           and then get the value at reg 1 and
           store it into reg 1 */
        ldr r1, add_of_strLen
        ldr r1, [r1]

        /* load in the address of message2 into
           reg 0 */
        ldr r0, add_of_message2

        /* print */
        bl printf

        /* branch to label 'end' */
        b end

.global main

main:
        /* load return address into reg 1
           and then get the value at the
           address and store it into reg 1 */
        ldr r1, add_of_return
        str lr, [r1]

        /* load address of message1 into reg 0
           and then print message1 */
        ldr r0, add_of_message1
        bl printf

        /* load in the necessary elements to
           scan in a string from the user */
        ldr r0, add_of_pattern
        ldr r1, add_of_string
        bl scanf

        /* prints the string given by the user */
        ldr r0, add_of_message3
        ldr r1, add_of_string
        bl printf

        /* load in the address of the user's string */
        ldr r1, add_of_string

        /*load in the address of strLen, then
          go to the address and store the value
          into r0 */
        ldr r0, add_of_strLen
        ldr r0, [r0]

        /* store strLen's address in reg 3 */
        ldr r3, add_of_strLen

        /* branch to label 'calcStrLen' */
        bl calcStrLen

/*Definitions of address values used */
add_of_message1: .word message1
add_of_message2: .word message2
add_of_message3: .word message3
add_of_pattern: .word pattern
add_of_string: .word string
add_of_strLen: .word strLen

/* external */
.global printf
.global scanf            

【问题讨论】:

    标签: assembly arm raspberry-pi


    【解决方案1】:
    string: .asciz ""
    

    我很确定它只是为字符串""(即一个字节)分配了足够的内存并填充它,这意味着您将获得内存:

    string: .byte 0
    next:   ; whatever comes next
    

    如果您随后在该位置存储两个或更多字节(例如通过 scanf()),您将进入一个痛苦的世界,因为会有某些描述损坏(next)。

    它损坏的内容取决于您的部分在内存中的布局方式。

    现在,至于如何修复它,这取决于您的汇编程序。大多数会有.defs 类型的伪操作码,用于定义任意大小的空间,因此您可以执行以下操作:

    string: .defs 128
    

    取决于你的汇编器支持什么。

    【讨论】:

    • 那么我怎样才能在我的'string'声明中分配足够的内存呢?
    • 我使用了 '.lcomm 字符串,128'。这就像一个魅力!非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多