如何在Arm Assembly中正确使用malloc函数打开文件?

时间:2019-05-08 05:34:03

标签: assembly arm checksum

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

我已经浏览了我的教授在网上发布的内容,但似乎根本没有帮助。它显示的就是这个

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

到目前为止,这是我的项目代码,以防万一。抱歉,如果要求太多,但是我到处都进行了研究,而手臂组装方面的帮助并不多。谢谢!

1 个答案:

答案 0 :(得分:1)

  

我打开文件。然后将字符串的大小放入变量

什么字符串?打开文件不会给您一个字符串,而是会给您一个文件描述符(可以传递给将来的read和/或write调用的整数“句柄”)。

如果您已经有一个长度为字符串的字符串,那么它已经在内存中,并且您不需要为其分配更多的空间。

您需要做的是找出文件 的长度,并将其作为arg传递给malloc。当然,这很简单,将其放在r0bl malloc中。您不需要从任何命名变量中存储/重新加载它,只需确保将其复制到一个调用保留的寄存器中,因为以后您可能还需要文件长度。


如果您仅限于ISO C库函数,则可以使用open / fstat代替POSIX fseek / ftell来查找文件多长时间。是。

但是,由于您是在asm中进行编程的,因此您知道要编写的操作系统和CPU,因此可以在打开前使用stat或在打开后使用fstat打开以查找文件长度。


您不需要为文件的整个大小分配空间:您可以读取4k,对其进行处理,再写入4k,然后再读取4k。

最后,您可以随时添加计算的内容。如果您需要排序或反转文件的行,则需要全部加载。 (或使用外部排序算法批量处理)。但是您将计算描述为“校验和”,因此文件数据未经修改就被复制,只需要追加即可。在上一次读写之后,您处于最佳位置。