如何在 arm 程序集中正确使用 malloc 函数打开文件?

How to properly use malloc function in arm assembly for opening files?

我正在使用 raspberry pi 进行手臂组装的学校项目。我的目标是打开一个输入文件并通过计算输入文件中的 ASCII 字符来计算校验和。然后打开一个输出文件,该文件将写入相同的消息,但在文本末尾添加 ASCII 值。我的教授要求为输入和输出数组动态分配内存。我的问题是我该怎么做,因为他从未向我们展示过如何使用它。我已经研究了如何在 C 中使用它,但我很难将这些知识应用到 arm assembly 中。

我已经根据我的教授在网上发布的 sheet 进行了检查,但似乎根本没有帮助。显示的就是这个

in n = 500;   
/* example  n has value of 500 */

dbptr = (char *) malloc(n)  
/* will allocate 500 bytes and dbptr will be the pointer to the beginning of 
the dynamically allocated array/buffer */

我脑子里想的是我要不要打开文件。然后将字符串的大小放入一个变量中,以变量为参数调用malloc?

.data
disInput:   .asciz  "Enter input file name: "
disOutput:  .asciz  "\nEnter output file name: "
disHash:    .asciz  "Enter hash seed: "
disOptions: .asciz  "\nGet checksum(1) or check integrity(2)?: "
disDone:    .asciz  "Checksum calculated!"
disSafe:    .asciz  "Integrity passed. File is safe."
disBad:     .asciz  "Integrity failed. File is not safe."
disNoFile:  .asciz  "No file exists"
disEmpty:   .asciz  "Empty file"
disWrong:   .asciz  "You entered a bad option\n"
formOption: .asciz  "%d"
formInFile: .asciz  "%s"
formOutFile:.asciz  "%s"
formHash:   .asciz  "%d"
inputFile:  .asciz  ""
outputFile: .asciz  ""
hashSeed:   .int    0
option:     .int    0

    .text
    .global main

main:
    push {ip,lr}
    b menu

menu:
    @ask user to enter input file name
    ldr r0,=disInput
    bl  printf

    @user input for file name
    ldr r0,=formInFile
    ldr r1,=inputFile
    bl  scanf

    @open file and check if empty or if it exists


    @ask user to enter hash seed
    ldr r0,=disHash
    bl  printf

    @user input for hash seed
    ldr r0,=formHash
    ldr r1,=hashSeed
    bl  scanf

    @ask user for option of get checksum or check integrity
    ldr r0,=disOptions
    bl  printf

    @user input for option
    ldr r0,=formOption
    ldr r1,=option
    bl  scanf

    @branch depending on user option
    ldr r4,=option
    ldr r5,[r4]
    cmp r5,#1
    beq option1
    cmp r5,#2
    beq option2
    b   wrongOption

option1:
    @ask user to enter output file name
    ldr r0,=disOutput
    bl  printf

    @user input for output file name
    ldr r0,=formOutFile
    ldr r1,=outputFile
    bl  scanf

    @branch to calculate checksum

option2:
    @
    ldr r0,=disDone
    bl  printf

wrongOption:
    @when user enters the wrong option
    ldr r0,=disWrong
    bl  printf
    b done

calculate:
    @where checksum is calculated

    @if option 1 then branch to done


done:
    mov r0,#0
    pop {ip,pc}
    .end

这是我目前为止为该项目编写的代码,以备不时之需。抱歉,如果它要求太多,但我到处都进行了研究,并且在手臂组装方面没有太多帮助。谢谢!

I open the file. Then put the size of the string into a variable

什么字符串?打开一个文件不会给你一个字符串,它会给你一个文件描述符(一个整数 "handle" 你可以传递给未来的 read and/or write 调用)。

如果你有一个已经有长度的字符串,它就已经在内存中了,你不需要为它分配更多的space。

你需要做的是找出 文件的长度 并将其作为参数传递给 malloc .那当然是微不足道的,把它放在 r0bl malloc 中。您不需要从任何命名变量 store/reload 它,只需确保将其复制到 call-preserved 寄存器,因为稍后您可能也需要文件长度。


如果您受限于 ISO C 库函数,而不是 POSIX open / fstat,您可以使用 fseek / ftell 找出文件的长度。

但是因为你在用 asm 编程,你知道你在写什么 OS 和 CPU,所以你可以使用 stat打开前或fstat打开后查找文件长度。


你不需要为文件的整个大小分配space:你可以读取4k,处理它,写入4k,然后读取另一个4k .

最后,您可以附加您即时计算的任何内容。如果您需要 排序 或反转文件的行,则需要全部加载。 (或使用外部排序算法分批工作)。但是您将您的计算描述为 "checksum",因此文件数据被原封不动地复制,您只需要追加即可。在上次读取 + 写入之后,您处于执行此操作的最佳位置。