Estoy en un problema interesante. Olvidé que estoy usando el sistema operativo de 64 bits & y escribí un código ensamblador de 32 bits. No sé cómo escribir código de 64 bits.Ejecutando código de ensamblado de 32 bits en un procesador Linux y 64 bit de 64 bit: explique la anomalía
Este es el código de ensamblaje x86 de 32 bits para Gnu Assembler (AT & T sintaxis) en Linux.
//hello.S
#include <asm/unistd.h>
#include <syscall.h>
#define STDOUT 1
.data
hellostr:
.ascii "hello wolrd\n";
helloend:
.text
.globl _start
_start:
movl $(SYS_write) , %eax //ssize_t write(int fd, const void *buf, size_t count);
movl $(STDOUT) , %ebx
movl $hellostr , %ecx
movl $(helloend-hellostr) , %edx
int $0x80
movl $(SYS_exit), %eax //void _exit(int status);
xorl %ebx, %ebx
int $0x80
ret
Ahora, este código debería funcionar bien en un procesador de 32 bits & 32 bits del sistema operativo correcto? Como sabemos, los procesadores de 64 bits son compatibles con versiones anteriores de procesadores de 32 bits. Entonces, eso tampoco sería un problema. El problema surge debido a las diferencias en las llamadas al sistema & mecanismo de llamada en el SO de 64 bits & SO de 32 bits. No sé por qué, pero cambiaron los números de llamada del sistema entre Linux de 32 bits & Linux de 64 bits.
asm/unistd_32.h define:
#define __NR_write 4
#define __NR_exit 1
asm/unistd_64.h define:
#define __NR_write 1
#define __NR_exit 60
De todos modos el uso de macros en lugar de números directos se paga. Es asegurar los números correctos de llamadas del sistema.
cuando ensamblo & enlace & ejecutar el programa.
$cpp hello.S hello.s //pre-processor
$as hello.s -o hello.o //assemble
$ld hello.o // linker : converting relocatable to executable
No está imprimiendo helloworld
.
En su GDB, mostrando:
- Programa salieron con código 01.
No sé cómo depurar en GDB. Usando el tutorial, intenté depurarlo y ejecutar instrucciones mediante registros de comprobación de instrucciones en cada paso. siempre me está mostrando "programa salido con 01". Sería genial si alguien pudiera mostrarme cómo depurar esto.
(gdb) break _start
Note: breakpoint -10 also set at pc 0x4000b0.
Breakpoint 8 at 0x4000b0
(gdb) start
Function "main" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y
Temporary breakpoint 9 (main) pending.
Starting program: /home/claws/helloworld
Program exited with code 01.
(gdb) info breakpoints
Num Type Disp Enb Address What
8 breakpoint keep y 0x00000000004000b0 <_start>
9 breakpoint del y <PENDING> main
He intentado ejecutar strace
. Esta es su salida:
execve("./helloworld", ["./helloworld"], [/* 39 vars */]) = 0
write(0, NULL, 12 <unfinished ... exit status 1>
- Explicar los parámetros de
write(0, NULL, 12)
llamada al sistema en la salida de strace? - ¿Qué exactamente está sucediendo? Quiero saber la razón por la cual exactamente su salida con exitstatus = 1?
- ¿Puede alguien mostrarme cómo depurar este programa usando gdb?
- ¿Por qué cambiaron los números de llamada del sistema?
- Cambie amablemente este programa de modo que se pueda ejecutar correctamente en esta máquina.
EDIT:
Después de leer la respuesta de Pablo R. Revisé mis archivos
[email protected]:~$ file ./hello.o
./hello.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped
[email protected]:~$ file ./hello
./hello: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped
Estoy de acuerdo con él en que estos deben ser ELF 32-bit reubicable & ejecutable. Pero eso no responde a mis preguntas. Todas mis preguntas aún son preguntas. ¿Qué está pasando exactamente en este caso? ¿Puede alguien responder mis preguntas y proporcionar una versión x86-64 de este código?
'' _start' o main' qué diferencia habría que hacer? – claws
@claws: solo Me hacen que el cambio de modo que el código podría construir y enlazar fácilmente con gcc, pero supongo que también significa que el código de inicio biblioteca de ejecución C se ejecutará antes del principal se llama. –
He editado mi pregunta. Además, cuando intento construir tu código usando 'gcc -Wall test.S -m32 -o test' Proporciona este error (los caracteres de subrayado se utilizan como separadores): /usr/bin/ld: omisión incompatible /usr/lib/gcc/x86_64-linux-gnu/4.4.1/libgcc.a al buscar -lgcc ______________ /usr/bin/ld: omitir /usr/lib/gcc/x86_64-linux-gnu/4.4.1/libgcc.a incompatible al buscar -lgcc ______________ /usr/bin/ld: no se puede encontrar -lgcc ______________ collect2: ld devuelto 1 estado de salida – claws