Exécution du code d'assemblage 32 bits sur un système Linux 64 bits & amp; Processeur 64 bits: Expliquer l'anomalie

Je suis dans un problème intéressant.J'oubliais, je suis sous 64 bits machine & OS et a écrit un 32 bits, le code d'assemblée. Je ne sais pas comment écrire 64 bits de code.

C'est le x86 32 bits assemblée code Assembleur Gnu (AT&T syntaxe) sur 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

Maintenant, Ce code doit s'exécuter correctement sur un processeur 32 bits & OS 32 bits à droite? Comme nous le savons processeurs 64 bits sont rétro-compatible avec les versions 32 bits des processeurs. Alors, qui également ne pas être un problème. Le problème se pose en raison de différences dans le système des appels & mécanisme d'appel dans les OS 64 bits & 32-bit OS. Je ne sais pas pourquoi, mais ils ont changé le système de numéros d'appel entre les versions 32 bits de linux & linux 64-bit.

asm/unistd_32.h définit:

#define __NR_write        4
#define __NR_exit         1

asm/unistd_64.h définit:

#define __NR_write              1
#define __NR_exit               60

De toute façon à l'aide de Macros à la place de numéro direct est payé. Sa s'assurer de la bonne système de numéros d'appel.

quand j'assemble & lien & exécuter le programme.

$cpp hello.S hello.s //pre-processor
$as hello.s -o hello.o //assemble
$ld hello.o //linker : converting relocatable to executable

Ses pas l'impression helloworld.

Dans gdb son montrant:

  • Programme terminé avec le code 01.

Je ne sais pas comment déboguer dans gdb. à l'aide de tutoriel, j'ai essayé de déboguer et d'exécuter l'instruction par instruction de la vérification des registres à chaque étape. c'est toujours en me montrant "le programme est sorti avec 01". Ce serait formidable si certains pouvaient me montrer comment déboguer ce.

(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

J'ai essayé de courir strace. C'est sa sortie:

execve("./helloworld", ["./helloworld"], [/* 39 vars */]) = 0
write(0, NULL, 12 <unfinished ... exit status 1>
  1. Expliquer les paramètres de write(0, NULL, 12) appel système dans la sortie de strace?
  2. Ce exactement qui se passe? Je veux savoir la raison pour laquelle exactement sa sortie avec exitstatus=1?
  3. Certains une, merci de me montrer comment déboguer ce programme à l'aide de gdb?
  4. Pourquoi ont-ils changer le système de numéros d'appel?
  5. De bien vouloir modifier ce programme de manière appropriée afin qu'il puisse s'exécuter correctement sur cette machine.

EDIT:

Après la lecture de Paul R réponse. J'ai vérifié mes fichiers

claws@claws-desktop:~$ file ./hello.o 
./hello.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped

claws@claws-desktop:~$ file ./hello
./hello: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped

Je suis d'accord avec lui que ceux-ci devraient être ELF 32-bit mobile & fichier exécutable. Mais cela ne veut pas répondre à mes à mes questions. Toutes mes questions, encore des questions. Ce qui se passe exactement dans ce cas? Quelqu'un peut s'il vous plaît répondre à mes questions et de fournir un x86-64 version de ce code?

source d'informationauteur claws