【问题标题】:How to read a .txt file using arm-assembly如何使用 arm-assembly 读取 .txt 文件
【发布时间】:2020-06-22 13:38:07
【问题描述】:

我刚刚开始学习 arm 汇编代码,基本示例很少。我需要一些帮助如何使用汇编代码 (ARM) 读取 .txt 文件。我试过nasm,它运行良好。但我的要求是运行 arm 代码(在 Linux 上),我不熟悉其语法。根据在线博客尝试了多种方法,但都不适用于我的情况。

下面是有效的 nasm 代码:​​

[SECTION .text]

global _start

_start:
    xor     eax, eax
    xor     ebx, ebx
    xor     ecx, ecx
    xor     edx, edx

    jmp     stub

openf:
    pop     ebx

    mov     al, byte 5      ; syscall 5, open
    xor     ecx, ecx
    int     0x80

    mov     esi, eax
    jmp     readloop

readloop:
    mov     ebx, esi
    mov     al, byte 3      ; syscall 3, read
    sub     esp, 1          ; reserve memory on stack for read byte
    lea     ecx, [esp]      ; load effective address of that memory
    mov     dl, byte 1      ; read count, 1 byte
    int     0x80            ; call read

    xor     ebx, ebx
    cmp     ebx, eax
    je      exit

    mov     al, 4           ; syscall 4, write
    mov     bl, 1           ; file descriptor 1, stdout
    mov     dl, 1           ; write count, 1 byte
    int     0x80            ; call write (4)

    add     esp, 1
    jmp     readloop

exit:
    mov     al, byte 1
    xor     ebx, ebx
    int     0x80            ; call exit (1)

stub:
    call    openf
    db      'flag.txt'

简而言之,我的任务是读取“标志”文件,使用 arm-assembly 源代码,其内容是我任务的解决方案。非常感谢任何帮助,因为它将帮助我更快地学习汇编代码。

更新: 我尝试使用 SWI,下面是读取和打印的代码:


    @@@ OPEN INPUT FILE, READ INTEGER FROM FILE, PRINT IT, CLOSE INPUT FILE
    .equ SWI_Open, 0x66 @open a file
    .equ SWI_Close,0x68 @close a file
    .equ SWI_PrChr,0x00 @ Write an ASCII char to Stdout
    .equ SWI_PrStr, 0x69 @ Write a null-ending string
    .equ SWI_PrInt,0x6b @ Write an Integer
    .equ SWI_RdInt,0x6c @ Read an Integer from a file
    .equ Stdout, 1 @ Set output target to be Stdout
    .equ SWI_Exit, 0x11 @ Stop execution
    
    .global _start
    .text
    _start:
    
    @ print an initial message to the screen
    mov R0,#Stdout @print an initial message
    ldr R1, =Message1 @ load address of Message1 label
    swi SWI_PrStr @ display message to Stdout
    
    @ == Open an input file for reading =============================
    @ if problems, print message to Stdout and exit
    ldr r0,=InFileName @ set Name for input file
    mov r1,#0 @ mode is input
    swi SWI_Open @ open file for input
    
    @ Save the file handle in memory:
    ldr r1,=InFileHandle @ if OK, load input file handle
    str r0,[r1] @ save the file handle
    
    @ == Read integers until end of file =============================
    RLoop:
    ldr r0,=InFileHandle @ load input file handle
    ldr r0,[r0]
    swi SWI_RdInt @ read the integer into R0
    bcs EofReached @ Check Carry-Bit (C): if= 1 then EOF reached
    @ print the integer to Stdout
    mov r1,r0 @ R1 = integer to print
    mov R0,#Stdout @ target is Stdout
    swi SWI_PrInt
    mov R0,#Stdout @ print new line
    ldr r1, =NL
    swi SWI_PrStr
    bal RLoop @ keep reading till end of file
    @ == End of file ===============================================
    EofReached:
    mov R0, #Stdout @ print last message
    ldr R1, =EndOfFileMsg
    swi SWI_PrStr
    
    .data
    .align
    InFileHandle: .skip 4
    InFileName: .asciz "newlog.txt"
    FileOpenInpErrMsg: .asciz "Failed to open input file \n"
    EndOfFileMsg: .asciz "End of file reached\n"
    ColonSpace: .asciz": "
    NL: .asciz "\n " @ new line 
    Message1: .asciz "Hello World! \n"

当我运行它时,我收到以下错误:


    $ qemu-arm myshell
    qemu: unhandled CPU exception 0x2 - aborting
    R00=00000001 R01=00010126 R02=00000000 R03=00000000
    R04=00000000 R05=00000000 R06=00000000 R07=00000000
    R08=00000000 R09=00000000 R10=000100e0 R11=00000000
    R12=00000000 R13=f6fff9b0 R14=00000000 R15=00008080
    PSR=00000010 ---- A usr32
    qemu: uncaught target signal 6 (Aborted) - core dumped
    Aborted

【问题讨论】:

  • ARM 是一个完全不同的 CPU 架构。要么找人为你翻译,要么学习 ARM 汇编。
  • 是的,我绝对同意你的看法。我不想翻译上面的 nasm 代码,如果有人可以告诉我如何使用 arm 汇编代码读取和打印文件,那会有所帮助。
  • 信息不足。具体来说,您拥有的 ARM 环境是什么?是Linux吗? IOS?安卓?文件读取不是纯粹的汇编操作,它需要操作系统的配合(即系统调用和/或 RTL),社区需要知道它是哪个操作系统。
  • 抱歉,错过了。在 Linux 上运行的 ARM 中编写代码是必需的。

标签: assembly arm nasm


【解决方案1】:

首先,您需要了解 ARM 程序集的基础知识。例如,命令是什么,寄存器是什么等。问题中的示例是针对 Intel x86 CPU 的。 ARM是不同的架构,所以区别不在于语法;命令、寄存器,甚至一些一般性的想法都不是英特尔的。例如,在 ARM 上,大多数算术命令使用三个寄存器,而不是 Intel 上的两个(a:=b+c 而不是a:=a+b)。另一方面,ARM 不支持对内存位置的算术运算 - 您必须先加载到寄存器中。

无论如何,ARM 的介绍超出了这样的 StackOverflow 答案的范围。阅读。 学习策略取决于您是否熟悉任何程序集(例如 Intel x86),以及您是否熟悉一般编程。 低级编程是一头完全不同的野兽。如果您只知道 C 或 Python,则必须进行一些主要的心智模型调整。如果您了解 x86 程序集,则需要从 ARM assembler manual 开始。

如果您是一般编程新手,别再搞汇编了,先学习一门高级语言。我是认真的。


综上所述,当涉及到文件读取时,Linux 系统调用就是这样。 ARM 约定是:系统调用 # 进入 R7,参数进入 R0..R5。您需要系统调用 2(打开)、0(读取)、3(关闭)。执行系统调用的命令是 swi(在旧的汇编器中)、svc #0(如果在 Thumb-2 模式下以 ARMv7+ 为目标,并且汇编器支持它)。

希望这会有所帮助。


编辑:看起来像问题的最新编辑中的系统调用序列,就是那个

.equ SWI_PrStr, 0x69 @ Write a null-ending string
...
swi SWI_PrStr @ display message to Stdout

来自 ARM 特定的系统调用规范,它与 Linux/ARM 系统调用接口无关,除了它们都是系统调用。有一个支持它们的第一方 ARM 模拟器,但 OP 并没有针对它。

【讨论】:

  • 感谢 Seva 的回答。我已经在研究高级语言 node.js、python 等,但是我第一次去 arm-assembly,这就是为什么在学习中遇到一些问题的原因。作为您的输入,我尝试按照您的 cmets 使用 SWI,并使用上面的代码更新了我的问题。遇到一些错误,你能看一下吗?或者请为您建议的伪代码提供一个 code-sn-p,因为它对我来说有点新理解。
  • 我没有 qemu-arm 也无法测试,但我的消息来源声称 Linux/ARM 上的系统调用约定不同。阅读我的最后一段 - r7 到系统调用 #(1 用于写入),SWI #0。尝试使用“打印字符串”部分。
猜你喜欢
  • 2014-09-21
  • 2014-04-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多