assembly - 我正在尝试使用汇编中的星号制成的圣诞树创建引导加载程序,但我不知道如何使用相同的循环进行打印
问题描述
我试图得到这样的东西
*
***
*****
*******
*********
***
***
我已经学会了如何创建一个循环并尝试调整相同的代码以多次使用该循环但失败了。以下是我到目前为止编写的代码
[BITS 16]
[ORG 0x7C00]
top:
;; Put 0 into ds (data segment)
;; Can't do it directly
mov ax,0x0000
mov ds,ax
;; si is the location relative to the data segment of the
;; string/char to display
mov si, fourSpace
call writeString
mov ch, 1 ; mov 1 into the register ch
call dotsLoop
mov si, threeSpace
call writeString
mov ch, 3 ; mov 3 into the register ch
call dotsLoop
mov si, twoSpace
call writeString
mov ch, 5 ; mov 5 into the register ch
call dotsLoop
mov si, oneSpace
call writeString
mov ch, 7 ; mov 7 into the register ch
call dotsLoop
mov ch, 9 ; mov 9 into the register ch
call dotsLoop
mov si, branchThreeSpace1
call writeString
mov ch, 3 ; mov 3 into the register ch
call dotsLoop
mov si, branchThreeSpace2
call writeString
mov ch, 3 ; mov 3 into the register ch
call dotsLoop
jmp $ ; Spin
dotsLoop:
mov si, dot ; print the dot
call writeString ; See below
dec ch ; reduce what is in ch by 1
cmp ch, 0 ; compare to see if what is store in ch is 0
jne dotsLoop ; if ch does not contain 0 call dotsLoop again.
mov si, cr ; print the newline code
call writeString ; See below
ret ; when ch contains 0 return back to main code
writeString:
mov ah,0x0E ; Display a chacter (as before)
mov bh,0x00
mov bl,0x07
nextchar:
Lodsb ; Loads [SI] into AL and increases SI by one
;; Effectively "pumps" the string through AL
cmp al,0 ; End of the string?
jz done
int 0x10 ; BIOS interrupt
jmp nextchar
done:
ret
fourSpace db ' ',0 ; For spacing
1dot db '*', 13,10,0
threeSpace db ' ',0 ; For spacing
3dot db '*',13,10,0
twoSpace db ' ',0 ; For spacing
5dot db '*',13,10,0
oneSpace db ' ',0 ; For spacing
7dot db '*',13,10,0
9dot db '*',13,10,0
branchThreeSpace1 db ' ',0 ; For spacing
branchdot1 db '*',13,10,0
branchThreeSpace2 db ' ',0 ; For spacing
branchdot2 db '*',13,10,0
times 510-($-$$) db 0
dw 0xAA55
但是,正如预期的那样,我在这些行的行错误开始时得到了预期的标签或指令
1dot db '*', 13,10,0
3dot db '*',13,10,0
etc..
谁能指导我如何将 dotsLoop 用于多个实例?
解决方案
1dot db '*',13,10,0 3dot db '*',13,10,0 5dot db '*',13,10,0 7dot db '*',13,10,0 9dot db '*',13,10,0 branchdot1 db '*',13,10,0 branchdot2 db '*',13,10,0
就像 Michael Petch 在评论中所写的那样,NASM 标签不能以数字 0-9 开头。
接下来,因为所有这些行都有相同的内容,所以你不需要重复 7 次。CH
登记册将使您所需要的一切变得不同。
此外,为了在程序中正确操作,您需要从行中删除该回车符和换行符对。
这是剩下的:
dot db '*', 0
fourSpace db ' ',0 ; For spacing threeSpace db ' ',0 ; For spacing twoSpace db ' ',0 ; For spacing oneSpace db ' ',0 ; For spacing branchThreeSpace1 db ' ',0 ; For spacing branchThreeSpace2 db ' ',0 ; For spacing
在这里,你也在重复自己 6 次!同样重要的是,您没有输出所需数量的空格!每次你写 4 个空格,因此不会产生圣诞树。
您可能需要的只是:
fourSpace db ' '
threeSpace db ' '
twoSpace db ' '
oneSpace db ' ', 0
threeSpace和branchThreeSpace1或branchThreeSpace2之间确实没有区别。它们都应该精确地输出 3 个空格字符。
谁能指导我如何将 dotsLoop 用于多个实例?
将上述内容应用于您的代码,您会发现它会起作用:
...
mov si, fourSpace
call writeString
mov ch, 1
call dotsLoop
mov si, threeSpace
call writeString
mov ch, 3
call dotsLoop
mov si, twoSpace
call writeString
mov ch, 5
call dotsLoop
mov si, oneSpace
call writeString
mov ch, 7
call dotsLoop
mov ch, 9
call dotsLoop
mov si, threeSpace
call writeString
mov ch, 3
call dotsLoop
mov si, threeSpace
call writeString
mov ch, 3
call dotsLoop
jmp $
dotsLoop:
...
writeString:
...
dot db '*', 0
fourSpace db ' '
threeSpace db ' '
twoSpace db ' '
oneSpace db ' ', 0
cr db 13, 10, 0
...
推荐阅读
- azure - 如何手动将 ASP.NET Core 应用程序的部署版本复制到 Azure Web 应用程序(应用服务)
- javascript - 有没有办法在 .NET 6 MAUI 中创建 shell 应用程序和 web 视图之间的双向通信?
- kubernetes - 将 Helm 图表自动部署到 Kubernetes
- javascript - 垂直条形图未正确显示
- python - 具有自动特定轮廓识别的视频裁剪
- java - 如何使用 WebClient 从分页的 REST API 获取数据
- reactjs - 在绘制元素之前如何获取元素?
- java - 如何在 Spring 中拥有多个相同的后端?
- ada - Gpr 文件,不要在源代码中包含所有目录
- android - 如何对全局文本使用 android 可访问性?