本文介绍了安装qemu后是否有命令可以运行任何ARM汇编文件(.s)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

限时删除!!

我最近运行了以下命令来安装qemu.

I have recently run the following commands to install qemu.

sudo apt-get install qemu-user
sudo mkdir -p /opt/arm/10
wget 'https://developer.arm.com/-/media/Files/downloads/gnu-a/10.2-2020.11/binrel/gcc-arm-10.2-2020.11-x86_64-arm-none-linux-gnueabihf.tar.xz?revision=d0b90559-3960-4e4b-9297-7ddbc3e52783&la=en&hash=985078B758BC782BC338DB947347107FBCF8EF6B' -O gcc-arm-10.2-2020.11-x86_64-arm-none-linux-gnueabihf.tar.xz
sudo tar Jxf  gcc-arm-10.2-2020.11-x86_64-arm-none-linux-gnueabihf.tar.xz  -C /opt/arm/10

现在没有.我想在 linux子系统 上编译并执行ARM文件.如果有人可以提供此问题的演练,那就太好了.我包括了一个.下面的链接到一些示例文件.我正在寻找一个通用命令,该命令将成功编译并运行所有这些文件.就像在C中, gcc -o test test.c 将编译并运行任何C文件一样.我没有树莓派

Now there are a no. of ARM files i would like to compile and execute on my linux subsystem. It would be great if someone could provide a walkthrough for this issue. I have included a no. of links below to some example files. I am looking for a general command that will successfully compile and run all these files. Just like in C where gcc -o test test.c would compile and run any C file. I do not have a raspberry pi

以下是一些示例ARM程序:

Here r a few example ARM programs:

.global _start
_start:
        MOV R1, #X
        MOV R2, #Y
        MOV R3, #Z
        MUL R5, R1, R1
        MUL R6, R2, R2
        ADD R5, R6
        MUL R6, R3, R3
        CMP R5, R6
        BEQ _same
        MOV R4, #0
        B _exit
_same:
        MOV R4, #1
_exit:
        MOV R0,  R4
        MOV R7,  #1
        SWI 0
.data
.global _start
_start:
        LDR R1, =X
        LDR R2, =Y
        LDR R3, =T
        LDR R4, [R1]
        STR R4, [R3]
        LDR R4, [R2]
        STR R4, [R1]
        LDR R4, [R3]
        STR R4, [R2]
_exit:
        MOV R0, #0
        MOV R7, #1
        SWI 0

.data
X: .word 0x16
Y: .word 0x21
T: .word 0x00
@ binary search for V in 25 element array.
        @ returns index for V if V is in the array.
        @ otherwise returns length of array (25).

        .global _start
_start:
        @ populate the array A
        LDR R1,=A
        MOV R2,#0x00
_populate_array:
        CMP R2,#MAX @ i == 25
        BEQ _search
        STR R2,[R1]
        ADD R1,#0x04
        ADD R2,#0x1
        B _populate_array
_search:
        MOV R6, #4      @ R6 == 4
        MOV R1, #0      @ R1 == left
        MOV R2, #MAX    @ R2 == right
        SUB R2, #1      @ R2 = MAX-1
_loop:
        CMP R1, R2      @ is left>right ?
        BGT _fail

        @ compute new middle position
        ADD R3, R1, R2  @ R3 = left + right
        LSR R3, R3, #1  @ middle = (left + right)/2
        @ each integer element uses 4 bytes of memory
        @ R7 is the memory address for the middle integer value in array A
        MUL R7, R3, R6  @ R7 = middle * 4

        @ obtain middle value at middle position
        LDR R4, =A      @ R4 == &A    (load address of A's 1st byte)
        ADD R4, R7      @ R4 == &A[m] (add offset of m to that address)
        LDR R5, [R4]    @ R5 == A[m]  (get value in A at that address)

        @ compare middle value to searched for value V
        CMP R5, #V      @ V==A[m]?
        BEQ _exit       @ we've found the value V
        BGT _left       @ is V somewhere in left half?

        @ if not, V must be somewhere in right half if at all
        MOV R1, R3      @ left = middle
        ADD R1, #1      @ left = left + 1
        B _loop

_left:                  @ A[m]<V (V would be somewhere in left half)
        MOV R2, R3      @ right = middle;
        SUB R2, #1      @ right = right - 1
        B _loop

_fail:
        MOV R3, #MAX
_exit:
        MOV R0, R5
        MOV R7, #1
        SWI 0
.data
.equ MAX, 25
A: .rept MAX
   .word 0
   .endr
.equ V, 17
.global main
main:
    @ Stack the return address (lr) in addition to a dummy register (ip) to
    @ keep the stack 8-byte aligned.
    push    {ip, lr}

    @ Load the argument and perform the call. This is like 'printf("...")' in C.
    ldr     r0, =message
    bl      printf

    @ Exit from 'main'. This is like 'return 0' in C.
    mov     r0, #0    @ Return 0.

    @ Pop the dummy ip to reverse our alignment fix, and pop the original lr
    @ value directly into pc — the Program Counter — to return.
    pop     {ip, pc}

    @ --------------------------------
    @ Data for the printf calls. The GNU assembler's ".asciz" directive
    @ automatically adds a NULL character termination.
message:
    .asciz "Hello, world.\n"
@ Here's how we will use the ARM registers R1-R5:
        @
        @ R1 - address of the next word
        @ R2 - the character counter
        @ R3 - contents of the next word
        @ R4 - next byte
        @ R5 - byte count

        .global _start

        @ program starts here
_start:
        LDR R1, =mystring

        @ initialise the character count (R2) to be 0
        MOV R2,#0

nextw:
        @ load the address of the next word into R3
        LDR R3,[R1]
        @ add 4 to the byte count
        MOV R5, #4

nextb:
        @ load next byte from word into R4
        MOV R4, R3
        @ use bitmask to get next byte value
        AND R4, #MASK
        @ if byte in R4 is 0, then we've found the "end of string" value
        CMP R4, #EOS
        BEQ endl
        @ otherwise, increment the character count by 1
    ADD R2, #1
        @ decrement bytes by 1
        SUB R5, #1
        @ while (bytes !=0) from the slide
        CMP R5, #0
        BEQ incr
        @ shift the contents of the word 8 bits right
        LSR R3, #8
        B nextb

incr:
        @ move to the next word address
        ADD R1,#4
        B nextw

endl:
        @ end of string '0' value found, we're done.
        @
        @ return character count as exit value
        MOV R0, R2
        MOV R7, #1
        SWI 0

.data
.equ MASK, 0x000000ff
.equ EOS, 0
mystring: .asciz "0123456789"

@ try other string examples
@ mystring: .asciz "thunderbirds"

提前谢谢!

推荐答案

您的问题的答案是否定的,因为它取决于您的汇编代码所针对的系统以及所执行的操作(我在这里仅提及了它),但实际上并没有ARM汇编文件之类的东西,因为此类文件可能使用不同的指令集,例如手臂/a32 thumb2/t32 ).

The answer to your question is no, because it depends on the system your assembly code was targeting, and on what it is doing (I am just mentioning it here, but there is not really such a thing as an ARM assembly file, since such a file may use different instruction sets, such as arm/a32, or thumb2/t32).

例如,在使用gcc的Linux系统上进行编译时,默认情况下入口点假定为 main ,而不是 _start -这就是为什么您的第一个程序必须具有稍作修改-您可能使用了 meld winmerge 来识别已修改/未修改版本之间的差异.该程序还必须使用Linux系统调用接口,这是所有程序的情况.参见此处,以获取有关 SVC / SWI 和Linux系统调用界面的更多信息.

For example, when compiling on a Linux system with gcc, the entry point is assumed to be main by default, not _start - this is why you first program had to be slightly modified - you could have used a program such as meld or winmerge for identifying the differences between the modified/unmodified versions. The program has to use the Linux system calls interface as well, which is the case of all your programs. See here for more information on SVC/SWI and the Linux system calls interface.

文章也是一本值得一读的书,它可以帮助您理解在调用入口点之前发生的事情.

This article is a worth reading as well for understanding what does happen prior to the entry point to be called.

如果要执行直接在仿真ARM处理器上运行的程序,则使用 qemu-system-arm arm-none-eabi-gcc 将是解决方案,但除非您有足够的知识,否则我不建议您这样做.

And if you wanted to execute programs directly running on an emulated ARM processor, using qemu-system-arm and arm-none-eabi-gcc would be the solution, but I would not recommend it until you will be more knowledgeable.

如果您想熟悉Windows上的ARM汇编,使用WSL和qemu-arm是一个很好的解决方案.

If you want to become familiar with ARM assembly on Windows, using WSL and qemu-arm is an excellent solution.

在这里,我假设您在提供的示例程序中将 _start 替换为 main .

I am assuming here you replaced _start by main in the example programs you provided.

您的第一个程序甚至无法汇编-确保在问题中使用它之前就已将其编译.

Your first program cannot even be assembled - make sure it does prior to use it in a question.

您的第二个程序确实使用以下命令进行编译/执行:

Your second program does compile/execute using:

/opt/arm/10/gcc-arm-10.2-2020.11-x86_64-arm-none-linux-gnueabihf/bin/arm-none-linux-gnueabihf-gcc -static -o 2 2.s
 qemu-arm 2

您的第三个程序确实使用以下命令进行编译/执行:

Your third program does compile/execute using:

/opt/arm/10/gcc-arm-10.2-2020.11-x86_64-arm-none-linux-gnueabihf/bin/arm-none-linux-gnueabihf-gcc -static -o 3 3.s
 qemu-arm 3

您的第四个程序确实使用以下命令进行编译/执行:

Your fourth program does compile/execute using:

 /opt/arm/10/gcc-arm-10.2-2020.11-x86_64-arm-none-linux-gnueabihf/bin/arm-none-linux-gnueabihf-gcc -static -o 4 4.s
qemu-arm 4
Hello, world.

您的第五个程序确实使用以下命令进行编译/执行

Your fifth program does compile/execute using:

/opt/arm/10/gcc-arm-10.2-2020.11-x86_64-arm-none-linux-gnueabihf/bin/arm-none-linux-gnueabihf-gcc -static -o 5 5.s
qemu-arm 5

底线一经修改,除第一个程序外,所有需要修复的程序都是用唯一"命令编译的,并用另一个唯一"命令执行.

Bottom line, once modified, all you programs but the first one, that need to be fixed, were compiled with a 'unique' command, and executed with a 'unique' other one.

您可以通过以下方式在某种程度上简化用于编译/运行程序的命令:

You can somewhat simplify the commands to be used for compiling/running your programs by:

在WSL中安装 binfmt-support :

sudo apt-get install binfmt-support

创建一个名为 etc/binfmt.d/qemu-arm.conf 的文件,其中包含以下两行:

Creating a file named etc/binfmt.d/qemu-arm.conf containing those two lines:

# /etc/binfmt.d/qemu-arm.conf
:arm:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff://opt/qemu-4.2.0-static/bin/qemu-arm:OC

这将导致您的系统透明地使用 qemu-arm 来运行您的可执行文件:

This will cause your system to transparently use qemu-arm for running your executable:

qemu-arm 4
Hello, world.

然后可以替换为:

./4
Hello, world.

将arm-none-linux-gnueabihf工具链可执行文件的位置添加到PATH.例如,可以通过将以下行添加到用户主目录中的 .bashrc 文件中来完成此操作:

Adding the location for the arm-none-linux-gnueabihf toolchain executables to your PATH. This can be for example be done by adding the following line to the .bashrc file present in your user home directory:

PATH=/opt/arm/10/gcc-arm-10.2-2020.11-x86_64-arm-none-linux-gnueabihf/bin:${PATH}

用于编译的命令可能是:

The command for compiling could then be:

 arm-none-linux-gnueabihf-gcc -static -o 4 4.s

这篇关于安装qemu后是否有命令可以运行任何ARM汇编文件(.s)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

1403页,肝出来的..

09-06 08:56