0

The CopyMemory function must copy part of the memory to another location.

CopyMemory
; The CopyMemory function receives the following parameters:
; R0: Address of the first 32-bit word to copy
; R1: Address of the last 32-bit word to copy
; R2: Destination address

ADD R4, R1, #4

Loop
CMP R4, R1
BEQ EndLoop

LDR R3, [R0]
STR R3, [R2]
ADD R0, R0, #4
ADD R2, R2, #4

B Loop
EndLoop

EndCopyMemory
BX LR

I have an error in the code, but I can't see what it is. Have I done something wrong?

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
David
  • 393
  • 3
  • 4
  • 11
  • Please comment each line with what you think it does so I can understand your though flow. I suppose your `CMP` instruction has incorrect operands. – fuz Oct 28 '20 at 18:55

1 Answers1

4

I would suggest you to learn how to debug your code when it is not working, this is still the best way to learn IMHO.

You could for example use an online assembler/debugger/emulator such as the cpulator.

copy/paste the code you want to test, assemble it, step into it while looking at the register values, memory content while your program is being executed step by step.

            .global _start
_start:
            ldr r0,= first
            ldr r1,= last
            ldr r2,= dst
            
            // The CopyMemory function receives the following parameters:
            // R0: Address of the first 32-bit word to copy
            // R1: Address of the last 32-bit word to copy
            // R2: Destination address
            add r4, r1, #4

loop:
            cmp r4, r1
            beq endloop

            ldr r3, [r0]
            str r3, [r2]
            add r0, r0, #4
            add r2, r2, #4

            b loop      
endloop:
            b .
            .data                   
first:      .word 0x11111111
            .word 0x22222222
            .word 0x33333333
last:       .word 0x44444444
dst:        .word 0x00000000
            .word 0x00000000
            .word 0x00000000            
            .word 0x00000000
            .end

enter image description here

enter image description here

If you are a Windows user and don't know anything about Linux, an alternative would be to use Windows versions of qemu-system-arm and GDB, but this would probably be more difficult to do for you at this stage.

They could be downloaded respectively from here and here.

If you are familiar/using a Linux system, using qemu-user as suggested by Peter Cordes in his comment would be a good solution as well. This could be done on a native Linux system, or by using a VirtualBox virtual machine on Windows, or by using one of the WSL or WSL2 Windows subsystems.

Frant
  • 5,382
  • 1
  • 16
  • 22
  • `qemu-user` is somewhat usable as a GDB-remote for single-stepping a simple block of ARM instructions. [How to single step ARM assembly in GDB on QEMU?](https://stackoverflow.com/q/20590155) / [How to run a single line of assembly, then see \[R1\] and condition flags](https://stackoverflow.com/q/39503997) – Peter Cordes Oct 28 '20 at 19:29
  • @Peter Cordes I do agree. However, its is not (I guess) easily available on a Windows system when Stefan Weil's [port](https://www.qemu.org/download/#windows) of qemu-system-arm works usually well in this kind of situation with a `qemu-virt`target machine and the GDB provided in a Linaro or ARM toolchain built for Windows. I tend to assume this kind of question may be asked by people not familiar with Linux at all,- I am not considering here running `qemu-user` under the `WS`L or the `WSL2` sub-systems, or using `VirtualBox`, because you still need to know about Linux somehow. – Frant Oct 28 '20 at 19:43
  • Ok, but why would anyone be using Windows? :P (Just kidding, but since the OP didn't mention Windows, I wasn't thinking of that at all. Interesting and fair point.) I would guess qemu-user might even work on cygwin, but maybe not; I don't know how low-level the mapping is, or whether it can handle the host versions of structs being different from guest. – Peter Cordes Oct 28 '20 at 20:21
  • Ah ah, I know... I am not sure about `qemu-user` under Cygwin (which I used to be very fan of) though , since it is, if I remember correctly, a POSIX emulation layer. My understanding of `qemu-user` is that the system calls called by the emulated programmed are simply being trapped/replaced by strictly equivalent system calls on the host system, which is way more easier/straight-forward to do. And for the cost (time-wise) of installing Cygwin on a AMD64 Windows PC, I would definitively prefer using `WSL` or `WSL2` starting from today. – Frant Oct 28 '20 at 20:38
  • ...but taste and colour, they say, is in the eye of the beholder... – Frant Oct 28 '20 at 20:43
  • I haven't looked into qemu-user internals. It can't always be as simple as just substituting call numbers; different architectures with different type-sizes can have different struct layouts. e.g. a 32-bit ARM guest on an x86-64 host will have different sizes for `long`, affecting things like time values in seconds on 32-bit kernel-ABI versions that haven't fixed the year-2038 bug yet. `qemu-arm` on my x86-64 Linux runs in 64-bit mode, not IA32-compat. Going as far as just making pure C POSIX function calls without any Linux-specific host requirements might be too much of a stretch, though. – Peter Cordes Oct 28 '20 at 21:18
  • I do agree - trapped/translated/converted was more what I had in mind. – Frant Oct 28 '20 at 21:37