Assembly 简化汇编程序
我目前有以下代码:Assembly 简化汇编程序,assembly,nested-loops,dos,masm,x86-16,Assembly,Nested Loops,Dos,Masm,X86 16,我目前有以下代码: .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
.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个循环使代码更简单。如何在汇编程序中执行嵌套循环?这是一种解决方案,仅使用8086/8088指令。它不依赖386指令,因此应该在任何8086/8088+仿真器中运行 这个程序的想法是我们在*和笑脸(02h)之间交替打印25个字符。我们每行打印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
这是一种仅使用8086/8088指令的解决方案。它不依赖386指令,因此应该在任何8086/8088+仿真器中运行 这个程序的想法是我们在*和笑脸(02h)之间交替打印25个字符。我们每行打印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
规范允许您更改为其他语言吗?:)也许你应该评论一下你的代码,告诉我们这个程序到底应该做什么?虽然你说你想简化为两个循环,但是也可以用一个循环来产生想要的效果(单循环也更简单),它实际上可以是一个循环。如果您不将输出包装成几行,那么它就是一个微笑星-微笑星流。。。人物。编写一个循环,在每个奇数迭代中打印一个星号,在每个偶数迭代中打印一个微笑(使用“test total_char_count,1”确定当前迭代是奇数还是偶数)。然后,如果模块5中已打印的字符总数为零,则将“如果”(cmp/检查)放入打印换行符的循环中。以某种方式检测打印字符数何时等于(列X行)并退出循环。您根本不需要循环。您只需一次BIOS调用即可显示该输出。规范允许您更改为其他语言吗?:)也许你应该评论一下你的代码,告诉我们这个程序到底应该做什么?虽然你说你想简化为两个循环,但是也可以用一个循环来产生想要的效果(单循环也更简单),它实际上可以是一个循环。如果您不将输出包装成几行,那么它就是一个微笑星-微笑星流。。。人物。编写一个循环,在每个奇数迭代中打印一个星号,在每个偶数迭代中打印一个微笑(使用“test total_char_count,1”确定当前迭代是奇数还是偶数)。然后,如果模块5中已打印的字符总数为零,则将“如果”(cmp/检查)放入打印换行符的循环中。以某种方式检测打印字符数何时等于(列X行)并退出循环。您根本不需要循环。您可以通过单个BIOS调用显示该输出。