2015-11-17 7 views
0

настоящее время у меня этот код:Simplify программа сборки

.model small 
.stack 100h 
.data 
.code 
    CLRSCR: 
     mov ax,0003h 
     int 10h 
    ROWCOLINIT: 
     mov dh,0 
     mov dl,0 
    MYLOOP: 
     mov ax,dx 
     mov ah,0 
     mov bl,2 
     div bl 
     cmp ah,0 
     je EVENCOL 
    ODDCOL: 
     mov al,2 
    CURSORINIT: 
     mov ah,02h 
     mov bh,0 
     int 10h 
    ATTRIBINIT: 
     mov ah,09h 
     mov bl,30h 
    PRINTCHAR: 
     mov cx,1 
     int 10h 
     inc dl 
     cmp dl,5 
     je RESETCOLINCROW2 
    DONTRESETCOL: 
     cmp dh,5 
     je EXIT 
     jmp MYLOOP 
    LOOP2: 
     mov ax,dx 
     mov ah,0 
     mov bl,2 
     div bl 
     cmp ah,0 
     je EVENCOL2 
    ODDCOL2: 
     mov al,42 
    CURSORINIT2: 
     mov ah,02h 
     mov bh,0 
     int 10h 
    ATTRIBINIT2: 
     mov ah,09h 
     mov bl,30h 
    PRINTCHAR2: 
     mov cx,1 
     int 10h 
     inc dl 
     cmp dl,5 
     je RESETCOLINCROW 
    DONTRESETCOL2: 
     cmp dh,5 
     je EXIT 
     jmp LOOP2 
    EXIT: 
     mov ah,4ch 
     int 21h 
    RESETCOLINCROW: 
     mov dl,0 
     inc dh 
     jmp DONTRESETCOL 
    RESETCOLINCROW2: 
     mov dl,0 
     inc dh 
     jmp DONTRESETCOL2 
    EVENCOL: 
     mov al,42 
     jmp CURSORINIT 
    EVENCOL2: 
     mov al,2 
     jmp CURSORINIT2 

end 

Мой выход программы:

*☻*☻* 
☻*☻*☻ 
*☻*☻* 
☻*☻*☻ 
*☻*☻* 

Я пытаюсь сделать этот код проще, используя 2 петли. Как мне сделать вложенные циклы в ассемблере?

+1

делает спецификации позволяют изменить на другой язык? :) – lordkain

+4

Возможно, вам стоит прокомментировать свой код и сообщить нам, что должна делать эта программа вообще? – zx485

+0

Хотя вы говорите, что хотите упростить до двух циклов, можно сгенерировать желаемый эффект с помощью одного цикла (также один простой цикл) –

ответ

0

Это одно решение, в котором используются только инструкции 8086/8088. Он не полагается на 386 инструкций, поэтому должен работать в любом эмуляторе 8086/8088 +.

Идея этой программы заключается в том, что мы печатаем 25 символов, чередующихся между * и смайликом (02h). Мы печатаем по 5 символов в строке (продвигаем курсор сразу после каждого символа), а затем переходим к началу следующей строки, если мы напечатаем 5 символов. Мы делаем это, пока не напечатаем количество обязательных символов (25).

Чтобы чередовать между * и смайликом лицо, я использую тот факт, что символ, который я хочу, зависит от того, является ли текущий символ, который я обрабатываю (в DI) является нечетным или четным. Если это даже я печатаю *, и если это нечетно, я печатаю смайлик.

Я представил комментарии в коде, чтобы дать представление о том, что происходит на каждом шагу. Я использую эти регистры в качестве переменных.

BP = Num of characters per row 
DI = Current character number we are processing 
BH = Current text page to print on 
BL = Attribute to use when printing to screen 
CX = Total number of characters to print with int 10h/ah=09h. Always = 1 
DH = Current cursor row 
DL = Current cursor column 

Код я использовал:

.model small 
.stack 100h 

.data 
outcharsarr db '*', 2 ; even = * odd = smiley face 

CHARSPERROW equ 5  ; Number of characters to print per row 
CHARSTOPRINT equ 25  ; Total number of characters to print 

.code 
    MAIN: 
    mov ax, @data  ; Use the proper data segment 
    mov ds, ax 

    mov ax,0003h   ; Clear screen 
    int 10h 

    xor dx, dx   ; Update cursor to 0,0 . DH=Row, DL=Column 
    mov ah, 2   
    int 10h 

    mov bp, CHARSPERROW; BP = Num of characters per row 
    xor di, di   ; DI = Current character number we are processing 
    mov bx, 0030h  ; BH = Current page to print on 
         ; BL = Attribute to use when printing 
    mov cx, 1   ; CX = Number of characters to print 

printloop: 
    xor si, si   ; Index to even/odd array 
    test di, 1   ; Is current character pos even/odd? 
    jz pl_evenpos  ; if even si=0 
    inc si    ; if odd si=1 
pl_evenpos:  
    mov al, outcharsarr[si] 
         ;Print the character out based on even/odd index 
    mov ah, 09h 
    int 10h 

    dec bp    ; dec number of chars still needed on current row 
    ja pl_nextcol  ; If we haven't printed enough for current row 
         ; goto next column 

    ; If we reach here we have printed the require number for this row 
    ; advance to beginning of next row 
    xor dl, dl   ; col=0 
    inc dh    ; row=row+1 
    mov ah, 2   ; Update cursor 
    int 10h 
    mov bp, CHARSPERROW 
         ; Reset the number of characters needed on current row 
    jmp pl_endloop 

pl_nextcol: 
    inc dl    ; col=col+1 
    mov ah, 2   ; Update cursor 
    int 10h 

pl_endloop: 
    inc di 
    cmp di, CHARSTOPRINT 
         ; Have we reached total number of characters to print? 
    jb printloop  ; If not got back and continue printing 

    mov ah,4ch   ; Exit program 
    int 21h 

end MAIN