Tenga en cuenta que el lenguaje ensamblador está definido por la herramienta, no por el objetivo. Para gnu assembler, hasta la fecha para el pulgar, particularmente con estos córtex-ms donde necesita / desea obtener la tabla de vectores correcta que comenzó con este problema:
.thumb
.globl _start
_start:
.word 0x20001000
.word reset
.word loop
.word loop
reset:
b reset
loop:
b loop
ensamble / desarme y puede ver el problema
Disassembly of section .text:
00000000 <_start>:
0: 20001000 andcs r1, r0, r0
4: 00000010 andeq r0, r0, r0, lsl r0
8: 00000014 andeq r0, r0, r4, lsl r0
c: 00000014 andeq r0, r0, r4, lsl r0
00000010 <reset>:
10: eafffffe b 10 <reset>
00000014 <loop>:
14: eafffffe b 14 <loop>
(una vez que sepa que las direcciones vectoriales deben ser la dirección orred con 1)
.thumb
.globl _start
_start:
.word 0x20001000
.word reset
.word loop
.word loop
.thumb_func
reset:
b reset
loop:
b loop
la solución mínima pero limpia es agregar .thumb_func para indicar que la próxima etiqueta que encuentre es una función de pulgar, no una dirección genérica.
(debe vincular no solo ensamblar / desensamblar)
Disassembly of section .text:
00000000 <_start>:
0: 20001000 andcs r1, r0, r0
4: 00000011 andeq r0, r0, r1, lsl r0
8: 00000012 andeq r0, r0, r2, lsl r0
c: 00000012 andeq r0, r0, r2, lsl r0
00000010 <reset>:
10: e7fe b.n 10 <reset>
00000012 <loop>:
12: e7fe b.n 12 <loop>
y que fija un vector.
.thumb
.globl _start
_start:
.word 0x20001000
.word reset
.word loop
.word loop
.thumb_func
reset:
b reset
.thumb_func
loop:
b loop
y que arregló el otro.
Disassembly of section .text:
00000000 <_start>:
0: 20001000 andcs r1, r0, r0
4: 00000011 andeq r0, r0, r1, lsl r0
8: 00000013 andeq r0, r0, r3, lsl r0
c: 00000013 andeq r0, r0, r3, lsl r0
00000010 <reset>:
10: e7fe b.n 10 <reset>
00000012 <loop>:
12: e7fe b.n 12 <loop>
agrega algo de C
.thumb
.globl _start
_start:
.word 0x20001000
.word reset
.word loop
.word fun
.thumb_func
reset:
b reset
.thumb_func
loop:
b loop
void fun ( void )
{
}
Disassembly of section .text:
00000000 <_start>:
0: 20001000 andcs r1, r0, r0
4: 00000011 andeq r0, r0, r1, lsl r0
8: 00000013 andeq r0, r0, r3, lsl r0
c: 00000015 andeq r0, r0, r5, lsl r0
00000010 <reset>:
10: e7fe b.n 10 <reset>
00000012 <loop>:
12: e7fe b.n 12 <loop>
00000014 <fun>:
14: 4770 bx lr
16: 46c0 nop ; (mov r8, r8)
Luego mire la salida del compilador de C
.cpu arm7tdmi
.eabi_attribute 20, 1
.eabi_attribute 21, 1
.eabi_attribute 23, 3
.eabi_attribute 24, 1
.eabi_attribute 25, 1
.eabi_attribute 26, 1
.eabi_attribute 30, 2
.eabi_attribute 34, 0
.eabi_attribute 18, 4
.file "fun.c"
.text
.align 1
.p2align 2,,3
.global fun
.arch armv4t
.syntax unified
.code 16
.thumb_func
.fpu softvfp
.type fun, %function
fun:
@ Function supports interworking.
@ args = 0, pretend = 0, frame = 0
@ frame_needed = 0, uses_anonymous_args = 0
@ link register save eliminated.
@ sp needed
bx lr
.size fun, .-fun
.ident "GCC: (GNU) 8.2.0"
(no importa que haya predeterminado el arm7, pero hay .thumb_func)
algunos lenguajes de ensamblaje tendrán directivas como proc o function u otras cosas similares que usas para declarar una etiqueta como una función en lugar de solo una dirección genérica para algo, por lo que cuando pruebes otros ensambladores para armar puedes encontrar eso.
si esto usa el ensamblador gnu, entonces .thumb_func debería solucionarlo. En su mente, pensaría que si esto es una orden con una que no sea una adición con una en caso de que la dirección sea correcta, podría terminar rompiéndola con la noción de agregar una a todo.
Lo mismo ocurre con la función de puntero de función en C, debes tener cuidado y puedes encontrarlo.
void loop ( void );
void hop ( unsigned int );
void fun ( void )
{
unsigned int x;
x = (unsigned int) loop;
hop(x);
}
void more_fun ( void )
{
unsigned int x;
unsigned short z[4];
z[0]=0x46c0;
z[1]=0x4770;
z[2]=0x46c0;
z[3]=0x46c0;
x = (unsigned int) z;
hop(x);
}
00000012 <loop>:
12: e7fe b.n 12 <loop>
00000014 <hop>:
14: 4700 bx r0
00000018 <fun>:
18: b510 push {r4, lr}
1a: 4803 ldr r0, [pc, #12] ; (28 <fun+0x10>)
1c: f7ff fffa bl 14 <hop>
20: bc10 pop {r4}
22: bc01 pop {r0}
24: 4700 bx r0
26: 46c0 nop ; (mov r8, r8)
28: 00000013 andeq r0, r0, r3, lsl r0
0000002c <more_fun>:
2c: b500 push {lr}
2e: 4b05 ldr r3, [pc, #20] ; (44 <more_fun+0x18>)
30: b083 sub sp, #12
32: 9300 str r3, [sp, #0]
34: 4b04 ldr r3, [pc, #16] ; (48 <more_fun+0x1c>)
36: 4668 mov r0, sp
38: 9301 str r3, [sp, #4]
3a: f7ff ffeb bl 14 <hop>
3e: b003 add sp, #12
40: bc01 pop {r0}
42: 4700 bx r0
44: 477046c0
48: 46c046c0
no es que vayas a ejecutar un código así, pero puedes ver el problema.
y una solución
void more_fun ( void )
{
unsigned int x;
unsigned short z[4];
z[0]=0x46c0;
z[1]=0x4770;
z[2]=0x46c0;
z[3]=0x46c0;
x = (unsigned int) z;
hop(x|1);
}
0000002c <more_fun>:
2c: b500 push {lr}
2e: 4b06 ldr r3, [pc, #24] ; (48 <more_fun+0x1c>)
30: b083 sub sp, #12
32: 9300 str r3, [sp, #0]
34: 4b05 ldr r3, [pc, #20] ; (4c <more_fun+0x20>)
36: 4668 mov r0, sp
38: 9301 str r3, [sp, #4]
3a: 2301 movs r3, #1
3c: 4318 orrs r0, r3
3e: f7ff ffe9 bl 14 <hop>
42: b003 add sp, #12
44: bc01 pop {r0}
46: 4700 bx r0
48: 477046c0
4c: 46c046c0
lo que puedes hacer muy bien es escribir un gestor de arranque y para obtener el salto al código cargado correctamente, necesitas resolverlo, hay una función de puntero que puedes probar y tal vez no escribir un poco de asm, pero te recomiendo el asm y orr con uno, es más probable que funcione.