1

I am attempting to learn ARM assembly. I decided to disassembly the "read" function and this is what I get. From the looks of it, it seems to be making a system call (svc #0) using the R7 register as the system call number.

mov ip, r7            # save R7
ldr r7, [pc, #0x14]   # get system call number and put it into R7 ??
svc #0                # make system call
mov r7, ip            # restore R7
cmn r0, #0x1000
bxls lr
rsb r0, r0, #0        # R0 = 0
b #2976848216

I am a bit confused though on why it is loading the system call number the way it is ("LDR r7, [PC, #0x14]"). Isn't this just doing in C code r7 = *(pc + 0x14)? I looked at other functions that might also use system calls (e.g. kill, wait, etc.) and they use a very similar convention (i.e. LDR R7, [PC, #0x14]).

This is on Android if it helps at all.

Thanks!

Jon
  • 1,381
  • 3
  • 16
  • 41
  • 1
    not the best way to learn arm assembly...try something simple like uint fun ( uint a, uint b ) { return a+b; } compile, disassemble and go from there. – old_timer Jun 07 '17 at 07:06
  • What other way were you expecting it to load the system call number? [How to use MOV instruction in ARM with an immediate number as the second operand](https://stackoverflow.com/questions/2624471/how-to-use-mov-instruction-in-arm-with-an-immediate-number-as-the-second-operand) explains the ways of loading constants. – Raymond Chen Jun 07 '17 at 19:03

1 Answers1

1
mov ip, r7            @# save R7
ldr r7, [pc, #0x14]   @# get system call number and put it into R7 ??
svc #0                @# make system call
mov r7, ip            @# restore R7
cmn r0, #0x1000       @
bxls lr               @
rsb r0, r0, #0        @# R0 = 0
.word 0x1234
.word 0xABCD

you pretty much left out the most important parts so had to improvise

00000000 <.text>:
   0:   e1a0c007    mov ip, r7
   4:   e59f7014    ldr r7, [pc, #20]   ; 20 <.text+0x20>
   8:   ef000000    svc 0x00000000
   c:   e1a0700c    mov r7, ip
  10:   e3700a01    cmn r0, #4096   ; 0x1000
  14:   912fff1e    bxls    lr
  18:   e2600000    rsb r0, r0, #0
  1c:   00001234    andeq   r1, r0, r4, lsr r2
  20:   0000abcd    andeq   sl, r0, sp, asr #23

And yes it is doing what you say it is doing, it is loading some value in r7 before making the system call, now what value is it as to why it is using a pc relative load (likely a constant that wont fit as an immediate, and/or a link time resolved value rather than compile time) and are there different values for different system calls and is r7 a parameter or not? Well you didnt provide enough information to talk about that. Once you have/see that information then that should be pretty obvious what those answers are...if any of those are is your question.

old_timer
  • 69,149
  • 8
  • 89
  • 168
  • Thanks old_timer, when I disassembled the code, I saw some other instructions after "rsb" but thought it didn't make sense so I left it out. I guess that was the data you needed :) It makes sense now though. – Jon Jun 07 '17 at 07:21
  • 1
    depending on the disassembler, and not uncommon with a fixed length instruction set like ARM in ARM mode, a disassembler might simply disassemble everything, including stuff that isnt an instruction as I have shown here, for other situations they may try to figure out code from data, I couldnt assemble your branch as written, but being an unconditional branch that means what follows it could be code or data, in your case it lines up with where the mystery data value would be. – old_timer Jun 07 '17 at 07:27
  • 1
    if this value is the same for all of these system calls you mentioned then it could still be a parameter or it could be something else, in either case there may also be passed in parameters (r0,r1,r2,r3) that you have not shown that may be used by the system call, I dont know the android system calling convention, and it may vary by version or implementation anyway, but that would be another path to understand this (looking up the android system calls on arm) – old_timer Jun 07 '17 at 07:30