|
主题 : : 实验9实现以及扩展 [待解决] |
回复[ 2次 ]
点击[ 1346次 ] | |
荣誉值:0
信誉值:0
注册日期:2007-10-22 14:47 |
assume cs:code, ds:data, ss:stack
data segment
db 18 ; 金字塔的塔高,即行数, 改变这个值,可以输出你想要的行数
db 'Hello, Welcome to MASM !'
data ends
stack segment
db 16 dup(0)
stack ends
code segment
start: mov ax, data
mov ds, ax
mov ax, 0B800H
mov es, ax
mov ax, stack
mov ss, ax
mov sp, 16
xor si, si
xor di, di
mov cx, 24
; print 'Hello, Welcome to MASM !'
mov ah, 10000001B
s: mov al, [si+1] ; 将要拷贝的字符送入al
mov es:[22*160 + 30*2 + di], ax ; 将要显示的字符及颜色送入显存的指定位置
add ah, 2 ; 改变字符颜色属性
and ah, 10001111B ; 字符总是闪动,而且背景色总是黑色
inc si ; 要拷贝的下一个字符偏移
add di, 2 ; 要存放下一个字符在显存中的偏移
loop s ; 循环拷贝并且显示所有字符
; 打印金字塔
xor bx, bx ; 显示的行数在显存中的偏移
xor cx, cx
mov cl, ds:[0] ; 获得金字塔塔高
mov si, 1 ; 行数计数器,记录当前显示的行数,即当前塔高
mov ah, 00000010B ; 字符颜色为绿色
t: push cx ; 保存外循环计数
dec cx ; 先输出 cx - 1 个空格
xor di, di ; space or star pos ; 字符在显存中的偏移
jcxz zero ; 如果显示空格数为0,则跳转,直接显示星号
mov al, 20h ; 空格的ascii
t0: mov es:[3*160 + 22 * 2 + bx + di], ax ; 将空格送入显存的指定位置
add di, 2 ; 获取下一个空格的在显存中的偏移
loop t0 ; 循环显示cx-1个空格
; 显示金字塔的一行
zero: mov cx, si ; 获取当前的行数
add cx, cx
dec cx ; 计算显示的星号个数, 即 2*行数-1个
mov al, 2ah ; 星号*的ascii
t1: mov es:[3*160 + 22 * 2 + bx + di], ax ; 接着当前行的最后一个空格,显示星号
add di, 2 ; 计算下一个星号的偏移
loop t1 ; 循环显示星号
add bx, 160 ; 定位显存的下一行,为下一层金字塔输出做准备
inc si ; 塔高计数器加1
pop cx ; 恢复外循环次数
loop t
mov ax, 4c00h
int 21h
code ends
end start
以上代码在屏幕的23行,30列的位置显示 "Hello, Welcome to MASM !"
字符是彩色交替的颜色,如果在纯dos下运行,看到的将是闪动的交替彩色字符串
从屏幕的第4行到第22行,显示一个金字塔形的*阵列,类似下面的效果:
*
***
*****
*******
..........
Hello, Welcome to MASM !
金字塔形的星号为绿色。
附上显示金子塔的c语言源程序,可以对照着看,这样能更好的理解金字塔是怎么输出的
/* test.c*/
#include <stdio.h>
#define N 5 /*金字塔塔高*/
int main()
{
int i, j, k;
int line = 1; /*行数计数器*/
for ( i = N; i > 0; i-- ) /*输出N行金字塔*/
{
for ( j = i - 1; j > 0; j-- ) /*先输出i-1个空格*/
printf("%c", ' ');
for ( k = 2 * line - 1; k > 0; k-- ) /*再输出 2*line-1 个星号*/
printf("%c", '*');
line++;
printf("\n");
}
return 0;
}
欢迎大家积极讨论,共同进步。【http://www.anijh.cn】 | | |