Montag, Januar 20, 2020

Wie finden Sie die Länge einer Zeichenfolge mit ARM-Montage auf einem Raspberry Pi

Ich bin derzeit lernen Baugruppe mit meinem RPI, das hat ARM-Architektur. Erstellt habe ich den folgenden code. Allerdings, wenn ich die Eingabe ein string („Hallo“ zum Beispiel) ein paar Dinge, die schief gehen.
Ich erhalte nicht die richtige Länge. Beispiel: „Hallo“ -> die Länge 8 (offensichtlich falsch).
Ich werde auch segfault, wenn der Eingang größer ist als 4 Zeichen. Beispiel: „Hallo“ -> die Länge 8 und dann segfaults.

Ich hoffe, ich mache offensichtlich etwas falsch! 🙂 Danke für Eure Hilfe im Voraus.

.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            

InformationsquelleAutor RBG | 2014-03-05

1 Kommentar

  1. 1
    string: .asciz ""
    

    Ich bin mir ziemlich sicher, dass nur reserviert genug Speicher für die Zeichenfolge "" (also ein byte) und füllt es, das heißt, Sie erhalten die Erinnerung:

    string: .byte 0
    next:   ; whatever comes next
    

    Wenn Sie dann zu gehen und zu speichern zwei oder mehr bytes an dieser Stelle (über scanf() zum Beispiel), du gehst in ein Welt von Schmerz, wie es sein werde, die Korruption der Beschreibung (bei next).

    Was es verdirbt hängt davon ab, wie Ihre Abschnitte erhalten im Speicher angeordnet.

    Nun, wie es zu beheben, das hängt von Ihrem assembler. Die meisten haben eine .defs Art von pseudo-opcode für die Definition von Raum von beliebiger Größe, so dass Sie könnte so etwas wie:

    string: .defs 128
    

    je nachdem, was Ihre assembler unterstützt.

    Wie konnte ich genügend Speicher in meiner Erklärung von ’string‘ dann?
    Ich benutzt ‚.lcomm string, 128‘. Diese funktionierte wie ein Charme! Dank einer Tonne!

    InformationsquelleAutor paxdiablo

Kostenlose Online-Tests