2017-06-08 5 views
0

J'ai besoin d'écrire une macro qui va insérer un espace entre chaque mot dans le tableau final. Comment pourrais-je y arriver et où dois-je l'initialiser et l'appeler?macro qui va insérer un espace entre les mots dans un tableau

Sortie désirée: "Say Cheese Okay".

sortie jusqu'à présent: "SayCheeseOkay"

Mon code à ce jour:

INCLUDE Irvine32.inc 

.data 
seq1 byte 'Sequence1 : ', 0 
seq2 byte 'Sequence2 : ', 0 
seq3 byte 'Sequence3 : ', 0 
fin_seq byte 'Final Sequence : ', 0 
s1 byte 'Say', 0 
s2 byte 'Cheese', 0 
s3 byte 'Okay', 0 
s4 byte 30 dup(?) 

.code 
main PROC 
    cld 
    mov edx, offset seq1 
    call WriteString 
    mov edx, offset s1 
    call WriteString 
    call Crlf 

    mov edx, offset seq2 
    call WriteString 
    mov edx, offset s2 
    call WriteString 
    call Crlf 

    mov edx, offset seq3 
    call WriteString 
    mov edx, offset s3 
    call WriteString 
    call Crlf 

    mov ecx, LENGTHOF s1 
    mov esi, offset s1 
    mov edi, offset s4 

copy1 : movsb 
    loop copy1 

    mov ecx, LENGTHOF s2 
    mov esi, offset s2 
    mov edi, offset s4 
    add edi, LENGTHOF s1 
    sub edi, 1 


copy2: movsb 
    loop copy2 
    mov ecx, LENGTHOF s3 
    mov esi, offset s3 
    mov edi, offset s4 
    add edi, LENGTHOF s1 
    add edi, LENGTHOF s2 
    sub edi, 2 

copy3: movsb 
    loop copy3 
    mov edi, offset s4 
    mov ecx, lengthof s4 
    mov al, ' ' 
    cld 

c1: 
    scasb 
    je c2 
    cmp ecx, 0 
    jz quit 
    loop c1 

c2: 
    cld 
    sub edi, 1 
    stosb 
    jmp c1 

quit: 
    mov ecx, LENGTHOF s4 
    mov esi, OFFSET s4 
    mov ebx, 0 

cycle: 
    mov al, [esi] 
    jmp exl 


exl: 
    movsb 
    loop cycle 
    mov edx, offset fin_seq 
    call WriteString 
    mov edx, offset s4 
    call WriteString 

    call Crlf 
    call ReadKey 
    call ReadChar 

exit 
main ENDP 
END main 
+0

Pourquoi réinitiez-vous 'edi' après la boucle' copy1'? (qui peut être remplacé par 'rep movsb'). N'a-t-il aucun but, ou vous n'avez simplement pas pensé à simplifier la tâche? Parce qu'une fois que vous allez "rationaliser" l'utilisation de 'edi', vous pouvez facilement mettre de l'espace entre' mov al ', '' '' 'stosb'. Regardez dans les registres du débogueur et le code, ce qu'il fait réellement, et quelles parties sont redondantes. Correction: en fait, cela copiera aussi le zéro-terminateur, et mettra de l'espace après, donc au lieu de stosb vous pouvez faire 'mov byte ptr [edi-1], ''' '. Et pourquoi avez-vous besoin de "macro"? : -o .. éviter les macros, si vous êtes en train d'apprendre l'assembleur, pas nécessaire. – Ped7g

+0

Pas de but spécial, comme vous l'avez dit, je l'ai fait de cette façon, parce que je ne savais pas comment le faire autrement. J'ai besoin de macro simplement parce que c'est une affectation: p – yTpo

+0

ok, prend un peu de temps pour choisir l'expérience ... pour un début de lancer ceci dans le débogueur et une seule étape dessus, en essayant de comprendre comment cela fonctionne, comment le résultat final la mémoire est stockée/accumulée, et quelle instruction particulière fait dans cette chaîne. Faire une macro d'instruction unique est bizarre, je n'ai aucune idée de comment je pourrais transformer 'mov [edi-1], ''' en macro significative. Peut-être que la mission a demandé une macro plus complexe, ou quelque chose. Quoi qu'il en soit, c'est bizarre de vous demander d'écrire une macro, si vous manquez de base, les macros sont bien utiles pour découper les petits bits répétitifs, mais pas pour les débutants – Ped7g

Répondre

0

Le marco devrait ressembler à ceci:

procedure MACRO ad1 
    mov byte ptr [edi-1],' ' 

ENDM 

et simplement l'appeler après la copy1 et copy2 méthodes. Et supprimez sub edi, 1 dans la méthode copy1.

+1

Essayez de ne pas appeler la procédure macro, ce sont des choses différentes. Les procédures dans la source sont du code machine réel, qui peut être appelé, et atterrira dans le code machine au même endroit, où vous les avez dans la source (par rapport à d'autres codes autour). Les macros sont injectées à l'endroit où vous les utilisez, elles sont donc comme un peu plus complexe à "remplacer tout" du texte source avant la compilation. Donc le nom "procédure" ne dit pas ce que cette macro fait, et il n'a rien à voir avec la procédure. J'irais avec quelque chose comme 'WriteSpaceAtPreviousEdi' = chance de comprendre ce qu'il fait après avoir lu. – Ped7g

0

Le plus drôle est que de la façon dont vous avez défini s1, s2, s3 en mémoire, vous pouvez « concaténer » les chaînes dans un seul juste en ce (ce n'est pas la solution à votre mission, car il faut effectivement tous le travail à partir de cela, c'est juste la démonstration comment les choses dans l'assemblage peuvent être rapides, si le programmeur raisonne soigneusement sur ce qui doit être fait et trouve l'algorithme optimal d'abord ... il montre également une manière plus significative d'utiliser une macro, bien que dans mon propre code je préférerais utiliser la procédure, à moins que des raisons de performances particulières ne rendent la macro nécessaire):

INCLUDE Irvine32.inc 

.data 
seq1 byte 'Sequence1 : ', 0 
seq2 byte 'Sequence2 : ', 0 
seq3 byte 'Sequence3 : ', 0 
fin_seq byte 'Final Sequence : ', 0 
s1 byte 'Say', 0 
s2 byte 'Cheese', 0 
s3 byte 'Okay', 0 

.code 

DisplayLabelValueEol MACRO labelStrPtr:REQ, valueStrPtr:REQ 
    mov  edx,labelStrPtr 
    call WriteString 
    mov  edx,valueStrPtr 
    call WriteString 
    call Crlf 
    ENDM 

main PROC 
    DisplayLabelValueEol OFFSET seq1, OFFSET s1 
    DisplayLabelValueEol OFFSET seq2, OFFSET s2 
    DisplayLabelValueEol OFFSET seq3, OFFSET s3 
    ; modify s1-s2-s3 memory to work as single concatenated string 
    mov  al,' ' 
    mov  [s2-1],al  ; replace the original s1 zero terminator 
    mov  [s3-1],al  ; replace the original s2 zero terminator 
    ; display result 
    DisplayLabelValueEol OFFSET fin_seq, OFFSET s1 

    call ReadKey 
    call ReadChar 
    exit 
main ENDP 

END main 

(Malheureusement, je n'ai pas MASM + Irvine32 partout, donc je ne l'ai pas testé, laissez-moi savoir si cela ne fonctionne pas).