2013-04-04 5 views
1

Я пытаюсь написать простую программу в x86 (используя MASM для компиляции). Цель состоит в том, чтобы написать аргументы командной строки для вывода (каждая в новой строке). Вот что я придумал до сих пор:сборка x86 аргументы командной строки

data1 segment 
    input db 40 dup (?) ;input     
data1 ends 


code1 segment 

START:       
    mov ax,seg input 
    mov ds,ax 
    mov dx,offset input 
    mov di, dx 

    mov si, 82h 
    mov cl,es:[80h]  


word: 
     mov al,es:[si] 
     mov ds:[di],al 
     inc si 
     inc di 

     cmp al,0Dh ;out of arguments? (if YES goto finish) 
     jz finish 

     cmp al,20h ;end of word? (if NO goto word) 
     jnz word 

    mov al, '$' ;line terminate 
    mov ds:[di], al 

    mov ah,09h  ;write string 
    int 21h 

    xor di,di ;prepare registry for new word 

    call new_line 


    loop word 

finish: 


    mov al, '$' 
    mov ds:[di], al 

    mov ah,09h  ;write last argument 
    int 21h 


    mov ax,4ch ;end program 
    int 21h 


new_line: 
    push ax 
    push bp 
    mov ax,0e0ah ;ah=0e-write char,al=0a-go to new line 
    int 10h 
    mov al,13  ;carriage return 
    int 10h 
    pop bp 
    pop ax 
ret 

code1 ends 
end START 

Это, кажется, работает хорошо, когда проходят под EMU8086, но после компиляции с MASM она дает правильные результаты только в 10% казней. Любая помощь будет высоко ценится

+0

Ваша программа не имеет сегмента стека и не должна работать на основе именно этого. Ваша программа также не подходит правильно. –

ответ

1

Перед тем, как начать копирование строки аргументов вы делаете:

mov dx,offset input 
mov di, dx 

Но если есть больше чем один аргумент, вы делаете это после того, как первый аргумент был напечатан:

xor di,di ;prepare registry for new word 

Это, вероятно, было mov di, dx, если вы абсолютно положительно, 100% уверены, что смещение input всегда будете 0.

2

Это было так давно я смотрел на любом ассемблере ... большие подсказки, а не here's your answer

Вы уверены, что ES загружается с соответствующим сегментом, так как вы не инициализацией его?

Обратите внимание, что при загрузке CL с содержимым 80H вы устанавливаете CL в LENGTH из командной строки.

Когда вы возвращаетесь к WORD (не хорошее имя для метки, btw - поскольку это ключевое слово), вы передаете следующий байт. Все очень хорошо и хорошо - но вы НЕ уменьшаете CL, количество символов в командной строке. Вы должны прыгать в инструкцию LOOP, которая уменьшает CX и возвращается к целевой метке, если 0 не достигнуто.

Вы очень тщательно (и правильно) сохранили BP и AX перед выполнением INT 10h Сохраняется ли для этих двух регистров достаточно? Возможно, другие регистры также изменены ...

Аналогично, INT 21H - есть ли какие-либо регистры, которые могут быть изменены выполнением процедуры за этим прерыванием? Если это так, вы должны PUSH их сначала и POP их обратно после выполнения обычной обработки.

Будьте очень осторожны, полагаясь на CR = 0DH = 13, чтобы закончить линию. Это будет отсутствовать, если доступное пространство для аргументов ПОЛНОСТЬЮ заполнено. Счетчик символов в CL более важен. Если вы правильно уменьшаете CL с помощью инструкции LOOP, вы не выиграете CR (IIRC), так как он не является частью счета. Это предполагает, конечно, что CX не изменяется все folderol проверки для пространства или выписывать линию ...

О, кстати - обычно, новая линия CR, LF или 0DH, 0AH - в этом порядке. На механических терминалах это буквально перемещало печатающую головку обратно в левую сторону, затем прокручивая бумагу вверх по линии. Печатающие головки были достаточно прочными и собрали большой импульс, когда они были возвращены против подпружиненной остановки. Следствием этого было то, что они часто отскакивали, а начальные символы следующей строки были бы распылены на первые несколько столбцов на распечатке, когда печатающая головка уладилась, каждая новая строка неумолимо мешала механикам все больше и больше корректировать.На самом деле, было необычно иметь новую линию CR CR LF CR, чтобы позволить времени механики оседать.

Смежные вопросы