0

我有一个项目,我想输入一个数字并说我输入 3,它会给你一个输出,

ZYX**XYZ

ZY****YZ

Z******Z

一个5会给你

ZYXWV**VWXYZ

ZYXW****WXYZ

ZYX******XYZ

ZY********YZ

Z**********Z

在我的项目中,我认为我的导师不会允许我使用数组,或者至少现在不允许,但这是我的想法。

我正在考虑为数字制作一个字符串,所以假设我得到一个 3。我会产生 ZYX* 并简单地将其反转以获得三角形的另一半。唯一的问题是,我不知道如何将字母一次一个地更改为星星。我正在考虑使用循环来做到这一点,但不知道该怎么做。我只知道下一个字符串是 ZY** 然后简单地反转它。

不要误会我的意思,我并不是要你们所有人为我做这件事,但也许给我一些关于如何处理它的指示或提示。谢谢你。

到目前为止,多亏了大家,我才能够想出这个。

TITLE MASM Template                     (main.asm)

; Description:
; 
; Revision date:

INCLUDE Irvine32.inc

.data
x       DWORD   ?
msg     BYTE    "Please input a number: " ,0dh,0ah,0

.code
;crlf
main PROC
    call    Clrscr

    MOV     edx, OFFSET msg         ; Moves message to input number into register
    call    WriteString         ; Displays message on screen to prompt user to input number
    call    readInt             ; Take the number that the user inputs
    MOV     x,eax                   ; Store it into x
    MOV     ecx, eax                ; For the loop counter  
    MOV     al, 'Z'                 ; Move Z to the register

L2:
    MOV     al, 'Z'             ; Resets al to z for loop

L1:                         ; Start of the loop with label L1
    call    WriteChar           ; To write the letters
    ;call crlf              ; To put in 'enter'
    SUB     al, 1               ; To Move the next char going downward
    LOOP    L1

    MOV     al, ' '
    call    WriteChar
    MOV     ecx, x                  ; Resets ecx for outside loop
    SUB     x, 1                    ; Decrements x for counter

    call    crlf                    ; To be tidy    
    LOOP    L2

    exit
main ENDP
END main

现在我只需要另一边。

4

2 回答 2

1

欢迎来到最黑暗的黑色计算机艺术 - 汇编程序!

让我们从汇编程序员的角度来看这个问题。

你有一个数字,比如说 BL(因为这是一个很好的汇编名称),你想要做的是产生 BL 输出行。假设 BL=5

现在,CX 作为一个计数器寄存器确实很好,所以如果我们将 BL 复制到 CL 并通过与自身进行异或来清除 CH,我们也有 CX=#lines。

在反转之前我们必须打印的字符数很方便地比这个多一个,所以我们可以增加 CX - 这是一个重要的数字,所以把它保存在 BP 中

每一行由字母'Z' 到('Z' - BH + 1) 和一个星号组成,然后是相反的,然后是一个新行。并且每一行,您将打印的字母数量减少一个,并在星号的数量上增加一个。

要生产一条生产线,我们会

  • 加载一个寄存器 - 比如说,DL,带有'Z'(DL,因为它作为'printme'例程的输出很方便)
  • 将其复制到另一个寄存器,比如 BH(寄存器到寄存器的移动比立即加载更快更小)
  • 从 BH 中减去 BL,得到一个神奇的值,'Z' - 5 = 'U' - 有铃声吗?

我们想打印一个字母的计数,所以如果我们将 BP 复制到 CX 中,那应该很有用。
这是我们想做 CX 次的事情:

  • 写出 DL 中的角色 - 稍作改动。
  • 通过 DECREMENTING 更改 DL 中的字符

然后我们需要输出另一个 BP 字节,所以再次将 BP 复制到 CX
这是我们想做 CX 次的事情:

  • 写出 DL 中的角色 - 稍作改动。
  • 通过 INCREMENTING 更改 DL 中的字符

然后发送 CR 和 LF

那么 - 有什么转折点?

好吧,如果 DL 中的字符小于或等于 BH 中的字符,我们想要替换一个星号,所以

  • 将 DX 保存在堆栈中
  • 如果 DL<=BH,则使用 ASTERISK 加载 DL
  • 输出DL
  • 从堆栈中弹出 DX,在我们替换星号之前恢复它的值。

完成那一行 - 减少 BL 中的行数;如果结果非零,则产生另一行

  • 如果它是零,我们都完成了。

请注意,通过减少 BL 中的行数,在生产线例程开始时从 DL 中减去的数字会减少,因此“更改为 aster”的值变为“V”、“W”...

现在让我们彻底变态。

您会注意到,两个 write-CX-characters 例程之间的唯一区别是一个 DECREMENTS 和另一个 INCREMENTS DL ...

让我们在开始之前将 SI 设置为 0FFFFH 并将 DI 设置为 1,只是为了笑。

现在 - DH 整场比赛都坐在替补席上。

假设我们编写了打印 CX 字符的例程,以便将 SI 添加到 DX。这将给我们第一次在循环中需要的减量。

  • 当循环结束时,假设我们交换 DI 和 SI。
  • 下次循环运行时,它将增加 DX,然后再次交换 SI 和 DI。

有用吧?

哦,当我们在扭曲时,我们可以通过使用它来存储 DL 而不是推动 DX 并将其弹出来让 DH 参与进来。将DL移动到DH,测试替换aster,写出并从DH恢复DL。

所以 - 这个例程的重点是它不依赖于存储中的字符串......

于 2013-04-18T15:06:01.340 回答
0

我写了一篇关于如何创建字符金字塔的教程。它使用 NASM 和 Windows API 而不是 Irvine,但本教程应该可以帮助您了解后勤问题。

于 2013-04-19T03:37:48.700 回答