2010-09-16 5 views
4

J'ai des problèmes pour accéder à la ligne de commande du processus à partir du programme d'assemblage Linux 64 bits. Pour reproduire cela avec un minimum de code, je fait ce programme 32 bits qui imprime 5 premiers caractères du nom du programme:Ligne de commande de processus sous Linux 64 bits

 
.section .text 

.globl _start 
_start: 
movl %esp, %ebp 

movl $4, %eax  # write 
movl $1, %ebx  # stdout 
movl 4(%ebp), %ecx # program name address (argv[0]) 
movl $5, %edx  # hard-coded length 
int $0x80 

movl $1, %eax 
movl $0, %ebx 
int $0x80 

Ce programme fonctionne. Quand je le traduis en 64 bits et tourne sous Linux 64, il n'imprime rien:

 
.section .text 

.globl _start 
_start: 
movq %rsp, %rbp 

movq $4, %rax 
movq $1, %rbx 
movq 8(%rbp), %rcx  # program name address ? 
movq $5, %rdx 
int $0x80 

movq $1, %rax 
movq $0, %rbx 
int $0x80 

Où est mon erreur?

Répondre

9

Vous chargez l'adresse correcte dans %rcx.

int 0x80 appelle ensuite l'interface syscall 32 bits. Cela tronque l'adresse à 32 bits, ce qui le rend incorrect. (Si vous utilisez un débogueur et de définir un point d'arrêt juste après le premier int 0x80, vous verrez qu'il revient avec -14 à %eax, qui est -EFAULT.)

Le deuxième syscall, exit, fonctionne bien parce que la troncature 32 bits ne fait aucun mal dans ce cas.


Si vous voulez passer une adresse de 64 bits à un appel système, vous devrez utiliser l'interface syscall 64 bits:

  • utilisation syscall, non int 0x80; Des registres différents sont utilisés: voir here; Les numéros d'appel système sont également différents: voir here.

Voici une version de travail de votre code:

.section .text 

.globl _start 
_start: 
movq %rsp, %rbp 

movq $1, %rax 
movq $1, %rdi 
movq 8(%rbp), %rsi  # program name address ? 
movq $5, %rdx 
syscall 

movq $60, %rax 
movq $0, %rdi 
syscall 
2

Comme indiqué dans le X86_64 ABI: Utilisez l'instruction syscall au lieu de int $0x80. Le noyau utilise des registres différents en 64 bits comme arguments syscall, et le numéro attribué à une fonction syscall varie également entre i386 et x86_64.

Un exemple - en allemand, désolé - peut être trouvé ici:
http://zygentoma.de/codez/linux_assembler.php

Questions connexes