2011-11-06 3 views
0

J'ai écrit un petit programme d'assemblage qui obtient et un fichier d'entrée, un fichier de sortie et un paramètre alternatif (soit -a ou -l). Maintenant, je veux distinguer dans le programme si l'utilisateur a passé un -a ou -l. Je sais que je peux passer le paramètre dans,% eax comme par exemple suit:assembler - Transmettre le paramètre et l'utiliser dans le programme

movl 16(%ebp),%eax 

Mais maintenant, je ne sais pas comment comparer% eax avec -a ou avec -l pour vérifier ce paramètre a été passé. Le programme s'exécute sur un système d'exploitation Linux 32 bits.

Quelqu'un peut-il me donner un indice s'il vous plaît?

Merci à l'avance,

enne

EDIT: Je x86-processeur. Voici quelques parties pertinentes du code

.section .data 
#######PROGRAM CODE### 

.section .text 

#STACK POSITIONS 
.equ ST_SIZE_RESERVE, 8 
.equ ST_FD_IN, 0 
.equ ST_FD_OUT, 4 
.equ ST_ARGC, 8  #Number of arguments 
.equ ST_ARGV_0, 12 #Name of program 
.equ ST_ARGV_1, 16 #Input file name 
.equ ST_ARGV_2, 20 #Output file name 
.equ ST_ARGV_3, 24 #-a or -l or nothing 
.equ ST_EXIT_CODE, 28 #Exit code 

.globl _start 
_start: 
###INITIALIZE PROGRAM### 
subl $ST_SIZE_RESERVE, %esp  #Allocate space for our pointers on the stack 
movl %esp, %ebp 

### Set standard error code 0 
movl $0, %ebx 
movl %ebx, ST_EXIT_CODE(%ebp) 
    movl ST_ARGV_3(%ebp),%eax #eax contains now the alternative paramter 
+0

Cela dépend-OS. Par exemple. sous Windows, vous devez appeler 'GetCommandLineW()' ou 'GetCommandLineA()' Win32 pour obtenir la ligne de commande, puis l'analyser. – atzz

+0

Montre ce que tu as dans la mesure où la solution exacte dépend fortement de ton environnement d'exécution, mais cela impliquera une sorte de comparaison de chaînes. – user786653

+0

De quel système d'exploitation s'agit-il? AFAIK Linux 32 bits ne garantit pas le contenu de '% ebp' et sur mon système c'est 0. Vouliez-vous dire'% esp' ou s'agit-il d'un autre système (ou avez-vous oublié un code de démarrage)? – user786653

Répondre

1

Dans « C » ce que vous voulez faire est:

if (strcmp(argv[3], "-a") == 0) { 
    /* stuff here */ 
} 

Puisque vous travaillez sans la bibliothèque standard C, vous devez créer vous-même strcmp. Ce n'est pas trop difficile car il revient à:

int strcmp(const char* str1, const char* str2) { 
    while (*str1 && *str1 == *str2) { 
     str1++; 
     str2++; 
    } 
    return *str1 - *str2; 
} 

Ou dans l'assemblage:

strcmp: 
    push %ebp 
    mov %esp, %ebp 
    movl 0x8(%ebp), %esi # str1 
    movl 0xc(%ebp), %edi # str2 
1: 
    movb (%esi), %al 
    or %al, %al # *str1 zero? 
    jz 2f 
    movb (%edi), %ah 
    cmp %ah, %al # equal to *str2? 
    jne 2f 
    # move to next character 
    inc %esi 
    inc %edi 
    jmp 1b 
2: 
    # result is difference between the two characters compared 
    movb (%esi), %al 
    subb (%edi), %al 
    movsx %al, %eax # Sign-extend to 32-bits 
    pop %ebp 
    ret 

Bien sûr, si vous ne l'utilisez réellement la différence calculée entre les cordes (il est utile pour le tri) vous pouvez simplifier légèrement la procédure.

Et l'utiliser:

# [snip] 
    movl ST_ARGV_3(%ebp),%eax #eax contains now the alternative paramter 

    push %eax  # first argument 
    pushl $dasha # second argument "-a" 
    call strcmp # compare strings 
    add $8, %esp # pop arguments 

    cmpl $0, %eax # Strings equal? 
    je strings_are_equal # Subtitute your own logic here 
    jmp strings_are_not_equal # and here.. 

Notez que cela suppose que vous avez une chaîne à comparer placée dans votre section de données comme:

.section .data 
dasha: .asciz "-a" 
+0

C'est exactement ce que je cherchais. Merci l'utilisateur! – enne87

Questions connexes