Reputation: 1899
On a Linux ARM platform, objdump
gives me the following for a specific function:
00000154 <compare_count>:
154: e92d4008 push {r3, lr}
158: e59f302c ldr r3, [pc, #44] ; 18c <compare_count+0x38>
15c: e5933014 ldr r3, [r3, #20]
160: e3530000 cmp r3, #0
164: 01a00003 moveq r0, r3
168: 08bd8008 popeq {r3, pc}
16c: e1530000 cmp r3, r0
170: ba000001 blt 17c <compare_count+0x28>
174: e3a00000 mov r0, #0
178: e8bd8008 pop {r3, pc}
17c: e59f000c ldr r0, [pc, #12] ; 190 <compare_count+0x3c>
180: ebfffffe bl 0 <printf>
184: e3a0006c mov r0, #108 ; 0x6c
188: e8bd8008 pop {r3, pc}
18c: 00000000 andeq r0, r0, r0
190: 00000038 andeq r0, r0, r8, lsr r0
Can it be translated back to C code? What would be the approximate translation?
Upvotes: 2
Views: 1073
Reputation: 28087
#define MAX 108
typedef struct X {
int pad[5];
int count;
} X_type;
X_type a;
int compare_count(int i, int i2, int i3) {
if (a.count == 0)
return a.count;
if (a.count < i) {
printf("%d", i2, i3, a.count);
return MAX;
}
return 0;
}
objdump
...somepadding...
00000154 <compare_count>:
154: e92d4008 push {r3, lr}
158: e59f3030 ldr r3, [pc, #48] ; 190 <compare_count+0x3c>
15c: e5933014 ldr r3, [r3, #20]
160: e3530000 cmp r3, #0
164: 0a000002 beq 174 <compare_count+0x20>
168: e1530000 cmp r3, r0
16c: a3a03000 movge r3, #0
170: ba000001 blt 17c <compare_count+0x28>
174: e1a00003 mov r0, r3
178: e8bd8008 pop {r3, pc}
17c: e59f0010 ldr r0, [pc, #16] ; 194 <compare_count+0x40>
180: ebfffffe bl 0 <printf>
184: e3a0306c mov r3, #108 ; 0x6c
188: e1a00003 mov r0, r3
18c: e8bd8008 pop {r3, pc}
190: 00000000 .word 0x00000000
194: 00000000 .word 0x00000000
Upvotes: 3
Reputation: 6354
The word at 0x18c isn't simply a zero, but a space holder for a global variable. (Its address being put at link time) This global variable seems to be a pointer on either a structure or an array consisting of integers. Let's assume it's an array.
The word at 0x190 contains the address of an external function.
extern int * a_global_array;
void unknown_function(void);
int a_function(int n)
{
int temp_val = a_global_array[5];
if (temp_val == 0) return 0;
if (temp_val >= n) return 0;
unknown_function();
return 108;
}
Upvotes: 3
Reputation: 20848
I'm not familiar with the ARM instruction set but after taking a quick look at the reference manual, here's my first attempt at it:
// push {r3, lr}
r3 = pc[44];
// ldr r3, [pc, #44] ; 18c <compare_count+0x38>
r3 = r3[20];
// ldr r3, [r3, #20]
if (r3 == 0)
// cmp r3, #0
{
return r3;
// moveq r0, r3
// popeq {r3, pc}
}
if (r3 >= r0)
// cmp r3, r0
// blt 17c <compare_count+0x28>
{
return 0;
// mov r0, #0
// pop {r3, pc}
}
printf(pc[12]);
// ldr r0, [pc, #12] ; 190 <compare_count+0x3c>
// bl 0 <printf>
return 108;
// mov r0, #108 ; 0x6c
// pop {r3, pc}
// looks like the rest of it is data or
// garbage values for padding alignment?
/*
andeq r0, r0, r0
andeq r0, r0, r8, lsr r0
*/
Upvotes: 1