0
@File: whichisthebiggest.s
    .global _start

_start:
    LDR R2,=A                   @load numbers in A-C
    LDR R2, [R2]
    LDR R3,=B
    LDR R3, [R3]
    LDR R4,=C
    LDR R4, [R4]

    LDR R1, = message_A         @load message A
    CMP R2, R3                  @compare A and B
    BLE who_is_the_biggest      @if B is greater, go to function
    MOV R3, R4                  @make C the new B
    CMP R2, R3                  @compare B and C
    BLE who_is_the_biggest_2    @if C is bigger, go to function
    B exit                      @end it, were done

who_is_the_biggest:             
    MOV R2, R3                  @since b is bigger, make B the new A
    LDR R1, =message_B          @change the message to B, since A isnt bigger

who_is_the_biggest_2:
    MOV R2, R3                  @put C in the number one spot. R2 is the answer
    LDR R1, =message_C          @change to message C since it is bigger than B

exit:
    MOV R0, #1                  @necessary to bring string
    SWI 0x69                    @prints string
    SWI 0x11                    @stop running program

.data
A:  .word 34                    @declare variables, numbers
B:  .word 10
C:  .word 54
message_A:  .asciz "A > B and A > C"    @declare strings
message_B:  .asciz "B > C and B > A"
message_C:  .asciz "C > A and C > B"

I am working on arm assembly raspberry Pi, I want to know how can I instead of message_A AND MESSAGE_B be in the code..I read them from command line argument when run by the user. and give a message in case two arguments not given.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
shumari
  • 1
  • 2
  • Read the ABI doc; I assume Linux on ARM uses the System V ABI like it does on x86, with the stack pointer pointing at argc on process startup. And above that, `argv[0]`, `argv[1]`, etc. You are using Linux, right? I added that tag because I *think* that's the default OS that RPi ships with. Although I thought Linux needed call numbers in `r7` these days, not as an immediate for `swi`. Is this some other OS? – Peter Cordes Feb 28 '20 at 04:53
  • Raspberry PI.... – shumari Feb 28 '20 at 05:02
  • RPi is hardware. It can run whatever software you want. – Peter Cordes Feb 28 '20 at 05:12
  • ok. should this do the job push {lr} add r11, sp, #4 how can I get first word second word. – shumari Feb 28 '20 at 05:16
  • what if no argument was given how can I check – shumari Feb 28 '20 at 05:16
  • By checking `argc`, of course. Or checking if `argv[1]` is a NULL pointer. (Technically a process could call `execve` with an empty argv so `argv[0]` is NULL, but if you trust your caller not to do that you could skip that check if you don't want to look at argc.) – Peter Cordes Feb 28 '20 at 05:29
  • argc should be add r11, sp, #0 ??? – shumari Feb 28 '20 at 05:31
  • `argc` is stored in memory (like the char* elements of `argv`), you need to `ldr r11, [sp]` not just do address calculations. – Peter Cordes Feb 28 '20 at 05:33
  • can u explain to me what this 3 do . add fp, sp, #4. and sub sp, sp, #8 and str r0, [fp, #-8] – shumari Feb 28 '20 at 05:37

1 Answers1

1

The argc and argv are passed on the stack. You can access them like this,

      ldr  r0, [sp]     /* Get argc... */
      add  r1, sp, #4   /* ... and argv ... */

argv is an array of pointers and the values will be passed in ASCII or text so you will need to convert the values to binary. If you have argc of four (first is program name), you can use below to get pointer to the number strings

 add r2, r1,#4
 add r3, r1,#8
 add r4, r1,#12

I would just code this in 'C' as it is a lot of hassle to do it in assembler for no real gain; except to educate your self. But you can see, a useful example with in-line assembler where the 'education' is actually useful. With in-line assembler you use the flexibility of assembler and leave all of the register allocation grinding to the 'C' compiler. A 2020 compiler is much better than those of the 1970/1980s and it is often the case that hand assembler will do a lot of mov Rn, Rm ... This is a waste of cycles and code space as SSA and register allocation algorithms will often eliminate them in compiled code. As well, compiled code is more likely to be correct than hand assembler.

artless noise
  • 21,212
  • 6
  • 68
  • 105
  • Having argc, argv[], and envp[] on the stack at process startup seems to be standard across ISAs for Linux, but is there an official doc that specifies this for ARM? For x86-64, this is all laid out [in the x86-64 System V psABI doc](https://github.com/hjl-tools/x86-psABI/wiki/X86-psABI). – Peter Cordes Mar 01 '20 at 18:53
  • I am not sure if there is a document, but I am not aware of anything in 'arch/arm/kernel' that does this. So, I think the handling of the argc/argv is done by generic Linux code and they would be the same for all architectures. – artless noise Mar 01 '20 at 20:30
  • Yeah, that makes sense. I'm just surprised nobody's bothered to write it down in an official generic document. (Or maybe they have somewhere in Linux's doc tree, just not in the System V generic gABI doc or any ARM-specific psABI I could find.) – Peter Cordes Mar 01 '20 at 20:41
  • 1
    https://refspecs.linuxfoundation.org/elf/index.html MIPS, alpha, 68k, x86, PowerPC, but no ARM (or riscv). I closed this are there are many similar questions already (for ARM). – artless noise Jan 01 '21 at 20:59