0

I am working on a school project that is in arm assembly using the raspberry pi. My goal is to open a input file and calculate the checksum just by counting the ASCII character in the input file. Then open a output file that will write the same message but add the ASCII value at the end of the text. My professor is asking to allocate memory dynamically for input and output arrays. My question is how would I go about that because he never showed us how to use it. I have researched how to use it in C but I am having a hard time putting that knowledge to arm assembly.

I have gone through a sheet from what my professor has posted online but it seems like it does not help at all. All it shows is this

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 */

What goes through my head is would I open the file. Then put the size of the string into a variable and call malloc with the variable as a parameter?

.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

Here is my code so far for the project just in case if its any help. Sorry if it is asking for too much but I have researched everywhere and there is not too much help with arm assembly. Thank you!

fsociety
  • 3
  • 1
  • 2
  • 1
    `I have researched how to use it in C but I am having a hard time putting that knowledge to arm assembly.` - it's just a call with a single parameter (size) and a pointer (address) as the return value. You already do calls (scanf, printf), so apply the same approach to malloc(). If you mean something else by your question - please be more specific. – tum_ May 08 '19 at 07:18
  • That makes sense and that is what I wanted to know. I think I got this now but one last thing to make sure. Would I first open the input file, then use read function to get size, then use that as the parameter for malloc()? And is fd being saved to r0? This the the sheet I am referring to if it helps. https://imgur.com/a/6F03PxT @tum_ – fsociety May 08 '19 at 07:35
  • Read @PeterCordes's answer on this. read() won't give you the size. Which OS is that? Looked at the link - comments suggest Linux. Yes, the return value comes in r0 ( assuming you work with ARM32 and not the newer 64-bit architecture). – tum_ May 08 '19 at 09:02
  • Apparently professors have something against assembler. This task is best done in 'C' or another high level language. No professional programmer would do this in 'C'. Why are professors so irresponsible to the profession that they continually as contrived questions like this. There are lots of other reasonable task to learn assembler with. Such painful activities will make students adverse to assembler. In this case you must track many variables which is tedious and you gain nothing by coding in assembler. You can not speed up calls to the 'C' library. – artless noise May 08 '19 at 13:29

1 Answers1

1

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

What string? Opening a file doesn't give you a string, it gives you a file descriptor (an integer "handle" you can pass to future read and/or write calls).

If you had a string with a length already, it would already be in memory and you wouldn't need to allocate more space for it.

What you need to do is find out the length of the file and pass that as an arg to malloc. That is of course trivial, put it in r0 and bl malloc. You don't need to store/reload it from any named variable, just make sure it's copied to a call-preserved register because you probably need the file length later, too.


If you're limited to ISO C library functions, instead of POSIX open / fstat, you can use fseek / ftell to find out how long a file is.

But since you're programming in asm, you do know what OS and CPU you're writing for, so you can use stat before opening or fstat after opening to find the file length.


You don't need to allocate space for the whole size of the file: you can read 4k, process it, write 4k, then read another 4k.

At the end, you can append whatever you calculated on the fly. If you needed to sort or reverse the lines of a file, you would need to load it all. (Or work in batches with an external sort algorithm). But you described your calculation as a "checksum", so the file data is copied unmodified and you just need to append. You're in a perfect position to do this after the last read + write.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
  • Makes perfect sense! I just have one final question when I use the open function and pass the parameters how do I put the O_RDONLY in? I did `ldr r1,=0x0000` and want to make sure that is right. @PeterCordes – fsociety May 08 '19 at 09:53
  • @fsociety: you have to look up the macro definitions in C header files, or compile a C function and look at the asm the compiler made. You shouldn't assume `O_RDONLY` = 0 if you haven't checked. – Peter Cordes May 08 '19 at 10:02
  • @fsociety: `ldr r1,=0x0000` does not look correct to me. The '=' is normally used for the LDR *pseudo-instruction* to load a 32-bit address, the assembler then translates it into the actual instruction(s) necessary to do the job. RTM. – tum_ May 08 '19 at 10:20
  • @tum_: `ldr r1,=constant` is a pseudo-instruction for putting arbitrary 32-bit constants into registers, regardless of them being addresses or not. But for a simple constant like `0`, you'd normally use `mov r1, #0` instead of tempting the assembler into loading a `0` from a PC-relative literal pool. (But GAS does assemble `ldr r1,=0` to a `mov`-immediate, not a load.) – Peter Cordes May 08 '19 at 10:23