如何在装配中反转和修改我的字符串?

时间:2013-04-18 07:11:23

标签: assembly masm irvine32

我有一个项目,我想输入一个数字并说我输入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

现在我只需要另一方。

2 个答案:

答案 0 :(得分:1)

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

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

你有一个数字,让我们说BL(因为这是一个很好的汇编名称),你想要做的是产生BL输出线。我们说BL = 5

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

我们在倒车之前打印的字符数量比这更方便了,所以我们可以增加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中减去的数字减少,因此“变为翠菊”值变为“V”,“W”。 ..

现在让我们彻底变态。

你会注意到两个写CX字符例程之间的唯一区别是一个DECREMENTS和另一个INCREMENTS DL ......

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

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

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

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

有用,是吗?

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

所以 - 这个例程的关键在于它不依赖于存储中的字符串......

答案 1 :(得分:0)

我写了一篇关于如何创建pyramid of characters的教程。它使用NASM和Windows API而不是Irvine,但是本教程可以帮助您解决后勤问题。