This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Unexpected behaviour calling an assembly function from c code. Is a bug?

Hi,

In the recent days i've been playing with assembly code in my raspberry 3B. I have a little code that shows how fast is my assembly code vs memcpy:

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdio.h>
#include <time.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
extern void move32b_LDM(uint32_t *ori, uint32_t size, uint32_t *dest);
extern void move32b_LDR(uint32_t *ori, uint32_t size, uint32_t *dest);
int main(int argc, char* argv[])
{
uint32_t *origen = malloc(1 << 27);
uint32_t *destino = malloc(1<<27);
if (origen == 0 || destino == 0)
return -1;
for (unsigned int i=0;i< (1<<25);i++)
*(origen+i) = i;
clock_t start = clock();
memcpy(destino,origen, 1 << 27);
clock_t finish = clock();
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

And i have my assembly code:

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
.global move32b_LDM
.global move32b_LDR
.p2align 2
.type move32b_LDM,%function
.section .text
move32b_LDM:
.func
push {R4,R5,R6,R7,R8}
ADD R8,R2,R1
loop: LDMIA R0!,{R4,R5,R6,R7}
STMIA R2!, {R4,R5,R6,R7}
CMP R8,R2
BNE loop
pop {R4,R5,R6,R7,R8}
MOV PC,LR
.endfunc
.type move32b_LDR,%function
move32b_LDR:
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Everything looks easy, but i get segmentation faults and invalid instruction exceptions everytime i call move32b_LDR function. Looking at assembly code something looks wrong:

 6ba:    f7ff ef7e     blx    5b8 <move32b_LDR>

You can see that the relative offset is not a even number as it should be and is causing a unexpected behaviour of the branch instruction. Gcc and ld should know that this branching is forbiden by the compiler and IMO is a bug of the compiler, isn't it? Can it be solve? Thanks you.

0