En los otros comentarios ya se dice correcto: el bit inicial solo tiene que extenderse sobre el resto de los bits anteriores. Pero por lo general no lo necesita, aquí está el por qué:
En C se hace automáticamente.
#include
- ¿Cómo explicaría los servidores de bases de datos y el alojamiento de bases de datos a un novato que solo sabe crear bases de datos en una máquina local?
- ¿Pueden ayudarme con respecto a la siguiente topología?
- ¿Se puede utilizar Machine Learning para el criptoanálisis?
- ¿Qué hay de nuevo en la tecnología informática?
- Dada una matriz de tamaño n, ¿cómo encuentra todos los subconjuntos posibles de la matriz de tamaño k?
int main () {
char i;
j corto;
para (i = -5; i <5; ++ i) {
j = i;
printf (“% d ->% d \ n”, i, j);
}
}
Si lo compilamos con “cc -g” y lo desarmamos con el editor hexadecimal radare2 obtenemos:
[0x00400430]> pdf @main
;- principal:
/ (fcn) sym.main 71
El | ; var int local_3h @ rbp-0x3
El | ; var int local_2h @ rbp-0x2
El | ; DATA XREF de 0x0040044d (entrada0)
El | 0x00400526 55 pushq% rbp; signext.c: 3 int main () {; .//signext.c:3
El | 0x00400527 4889e5 movq% rsp,% rbp
El | 0x0040052a 4883ec10 subq $ 0x10,% rsp
El | 0x0040052e c645fdfb movb $ 0xfb, -3 (% rbp); signext.c: 7 para (i = -5; i <5; ++ i) {; .//signext.c:7
El | , = <0x00400532 eb2c jmp 0x400560
El | El | ; JMP XREF de 0x00400564 (sym.main)
El | .–> 0x00400534 660fbe45fd movsbw -3 (% rbp),% ax; signext.c: 8 j = i
; ; .//signext.c:8 .for (i = -5; i <5; ++ i) {
El | || 0x00400539 668945fe movw% ax, -2 (% rbp)
El | || 0x0040053d 0fbf55fe movswl -2 (% rbp),% edx; signext.c: 9 printf (“% d ->% d \ n”, i, j); ; .//signext.c:9 ..j = i;
El | || 0x00400541 0fbe45fd movsbl -3 (% rbp),% eax
El | || 0x00400545 89c6 movl% eax,% esi
El | || 0x00400547 bff4054000 movl $ str._d _____ d_n,% edi; “% D -% d.” @ 0x4005f4
El | || 0x0040054c b800000000 movl $ 0,% eax
El | || 0x00400551 e8aafeffff callq sym.imp.printf
El | || 0x00400556 0fb645fd movzbl -3 (% rbp),% eax; signext.c: 7 para (i = -5; i <5; ++ i) {; .//signext.c:7
El | || 0x0040055a 83c001 addl $ 1,% eax
El | || 0x0040055d 8845fd movb% al, -3 (% rbp)
El | || ; JMP XREF de 0x00400532 (sym.main)
El | | `-> 0x00400560 807dfd04 cmpb $ 4, -3 (% rbp); [0x4: 1] = 2; .//signext.c:7
El | `== <0x00400564 7ece jle 0x400534
El | 0x00400566 b800000000 movl $ 0,% eax
El | 0x0040056b c9 licencia; signext.c: 12}
\ 0x0040056c c3 retq
Como puede ver, el compilador hace la extensión con un solo comando. En 8086 tienes CBW, CWDE y CDQE para convertir el byte en AL para redactar la palabra en AX a EAX o el EAX de 32 bits a RAX.
En x86_64 obtienes el comando MOVSX adicional al que hará eso por ti, correlacionando con la longitud de los registros que estás usando.
En este código, MOVSBL y MOVSBW lo hacen.
Así que no lo hagas a mano, deja que el compilador lo haga por ti. Él es bueno en eso. No puedes vencerlo. Está usando el código de ensamblaje correcto para eso, que usa exactamente un ciclo.