Sono in un problema interessante. Ho dimenticato di utilizzare il sistema operativo a 64 bit & e ho scritto un codice assembly a 32 bit. Non so come scrivere codice a 64 bit.Esecuzione di codice assembly a 32 bit su un processore Linux a 64 bit e 64 bit: Spiegazione dell'anomalia
Questo è il codice assembly x86 a 32 bit per Gnu Assembler (sintassi AT &) su 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
Ora, questo codice dovrebbe funzionare bene su un processore a 32 bit a 32 bit del sistema operativo & giusto? Come sappiamo i processori a 64 bit sono compatibili con le versioni precedenti con processori a 32 bit. Quindi, anche questo non sarebbe un problema. Il problema si pone a causa delle differenze nelle chiamate di sistema meccanismo di chiamata & in OS a 64 bit OS & sistema operativo a 32 bit. Non so perché, ma hanno cambiato i numeri di chiamata di sistema tra linux a 32 bit & linux a 64 bit.
asm/unistd_32.h definisce:
#define __NR_write 4
#define __NR_exit 1
asm/unistd_64.h definisce:
#define __NR_write 1
#define __NR_exit 60
Comunque utilizzando Macro invece dei numeri diretti è pagato. Garantisce i numeri di chiamata di sistema corretti.
quando assemblare & collegamento & eseguire il programma.
$cpp hello.S hello.s //pre-processor
$as hello.s -o hello.o //assemble
$ld hello.o // linker : converting relocatable to executable
Non stampa helloworld
.
In gdb la sua mostra:
- programma è terminato con il codice 01.
non so come eseguire il debug in gdb. usando il tutorial ho provato a eseguirne il debug e ad eseguire le istruzioni con i registri di controllo delle istruzioni ad ogni passaggio. mi mostra sempre "il programma è uscito con 01". Sarebbe bello se qualcuno su potrebbe mostrarmi come eseguire il debug di questo.
(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
Ho provato a eseguire strace
. Questa è la sua uscita:
execve("./helloworld", ["./helloworld"], [/* 39 vars */]) = 0
write(0, NULL, 12 <unfinished ... exit status 1>
- spiegare i parametri di
write(0, NULL, 12)
chiamata di sistema nella produzione di strace? - Cosa sta succedendo ? Voglio sapere il motivo per cui esattamente è uscito con exitstatus = 1?
- Qualcuno può mostrarmi come eseguire il debug di questo programma utilizzando gdb?
- Perché hanno cambiato i numeri di chiamata di sistema?
- Gentilmente modificare questo programma in modo appropriato in modo che possa funzionare correttamente su questa macchina.
EDIT:
Dopo aver letto la risposta di Paolo R. Ho controllato i miei file
[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
Sono d'accordo con lui che questi dovrebbero essere ELF a 32 bit relocatable & eseguibile. Ma questo non risponde alle mie mie domande. Tutte le mie domande sono ancora domande. Cosa sta succedendo esattamente in questo caso? Qualcuno può rispondere alle mie domande e fornire una versione x86-64 di questo codice?
'_start' o' main' che differenza farebbe? – claws
@claws: ho apportato questa modifica solo in modo che il codice potesse essere creato e collegato facilmente con gcc, ma suppongo che significhi anche che il codice di avvio della libreria di runtime C verrà eseguito prima che venga chiamato main. –
Ho modificato la mia domanda. Inoltre, quando provo a creare il tuo codice usando 'gcc -Wall test.S -m32 -o test' Fornisce questo errore (i caratteri di sottolineatura sono usati come separatori): /usr/bin/ld: saltare incompatibile /usr/lib/gcc/x86_64-linux-gnu/4.4.1/libgcc.a durante la ricerca di -lgcc ______________ /usr/bin/ld: saltando incompatibile /usr/lib/gcc/x86_64-linux-gnu/4.4.1/libgcc.a durante la ricerca di -lgcc ______________ /usr/bin/ld: impossibile trovare -lgcc ______________ collect2: ld ha restituito 1 stato di uscita – claws