Assembly 有人能解决汇编语言上的显示错误吗
当我用汇编语言编写程序时,更具体地说是.asm文件 在编译它并在tasm编译器上执行时,我们显示了一个错误 我们得到的不是数字而是相应的asci代码 我在网上查过, 和朋友们一起裁判 我目前正在使用Tasm编译器Assembly 有人能解决汇编语言上的显示错误吗,assembly,x86-16,tasm,Assembly,X86 16,Tasm,当我用汇编语言编写程序时,更具体地说是.asm文件 在编译它并在tasm编译器上执行时,我们显示了一个错误 我们得到的不是数字而是相应的asci代码 我在网上查过, 和朋友们一起裁判 我目前正在使用Tasm编译器 .model small .stack 100h .data num db 5,4,7,0,1,9,3,6,8,2 msg db 'NUMBERS in sorted order:$'; .code mov ax,@data mov ds,ax mov es,ax mov ah,00h
.model small
.stack 100h
.data
num db 5,4,7,0,1,9,3,6,8,2
msg db 'NUMBERS in sorted order:$';
.code
mov ax,@data
mov ds,ax
mov es,ax
mov ah,00h
mov al,ah
qq:
mov cl,09h
mov si,00h
yy:
mov al,num[si]
inc si
cmp al,num[si]
jc xx
mov bh,num[si]
mov num [si],al
dec si
mov num[si],bh
inc si
xx:
dec cl
jnz yy
dec bl
jnz qq
lea dx,msg
mov ah,09h
int 21h
lea dx,num
mov ah,09h
int 21h
mov ah,4ch
int 21h
end
产量为
num db 5,4,7,0,1,9,3,6,8,2
您在这里定义的是,在num指向的地址中,您使用了一个字节表示5,然后是一个字节表示4,一个字节表示7,等等
msg db 'NUMBERS in sorted order:$';
这里你制作了一个字符串,一个字符串是为了让我们的生活更轻松,你在这里所做的是在msg指向的地址中,你定义了一个字节为78(在ASCII中N是78),字节为85,等等
这里有两个解决方案,
或者您正在将数字更改为字符串
num db "5 4 7 0 1 9 3 6 8 2"
或者,你要在每个数字上加上48个十进制数(ASCII码为48-0,49-1,50-2等)
考虑到这个程序适用于num变量中的10个数字,它只适用于0-9之间的数字
正如屏幕截图所示,TASM无法找到您的源文件。这意味着链接器TLINK的后续使用将作用于对象文件的旧版本,该版本不包括对程序源的最新修改。在这种情况下,为什么还要运行应用程序
为什么它根本不起作用
此DOS输出函数要求DX
指向以“$”结尾的文本。您的代码不提供此功能。缺少“$”并且地址num处的字节不是您可能认为的字符“0”到“9”
当numdb5,4,7,0,1,9,3,6,8,2
放置字节5,4,7。。。在内存中,如果这些字节是53、52、55,…,则上述使用的DOS功能可以正常工作。。。(正常人会写“5”、“4”、“7”和……)
我的解决方案是不使用函数09h,而是编写一个使用函数02h的循环。这样,您可以通过添加48轻松地将数字转换为文本形式
mov cx, 10
lea si, num
More:
mov dl, [si]
inc si
add dl, 48
mov ah, 02h
int 21h
dec cx
jnz More
为什么它不好用
您的程序无处初始化此BL
寄存器!根据BL
中碰巧出现的值,您的代码将进行太少的迭代来对数字进行排序,或者您的代码可能进行了太多的数百次迭代。幸运的是,这些冗余迭代不会破坏最终结果,但仍然
该程序实现了一个冒泡排序算法。冒泡排序的思想是,最大的元素将冒泡到顶部(数组的后部)。这立即意味着在完成内部循环时,您不再需要查看这个最大的元素,因为它位于其最终位置每次内部循环完成时,您可以将任务减少1个元素。您的代码不这样做,因为您总是设置CL=9
这是正确使用BL
的代码:
mov BL, 9
qq:
mov cl, BL
mov si,00h
yy:
mov al,num[si]
inc si
cmp al,num[si]
jc xx
mov bh,num[si]
mov num [si],al
dec si
mov num[si],bh
inc si
xx:
dec cl
jnz yy
dec bl
jnz qq
写得好一点
- 给出标签的描述性名称(我的选择,其他人会做出其他选择)
- 更喜欢
而不是JB
,因为下面的跳转更好地表达了这里发生的事情JC
- 使用可用的寻址模式。如果写入
mov num[SI-1],al
- 清除寄存器通常是通过对寄存器本身进行异或来完成的。代替
,您可以编写mov-si,0
xor-si,si
- 添加一些解释性评论
mov dx, 9 ;This is number of elements minus 1
OuterLoop:
mov cx, dx ;This is what actually reduces the task
xor si, si
InnerLoop:
mov al, num[si] ;Reading 2 successive array elements
mov bl, num[si+1]
cmp al, bl ;Comparing as UNsigned numbers
jb NoSwap
mov num[si], bl ;Writing them in reverse order
mov num[si+1], al
NoSwap:
inc si
dec cx
jnz InnerLoop
dec dx
jnz OuterLoop
草案2(失去大部分位移):
草案3(失去所有位移…真的没有特殊原因):
您需要包含更多关于输出确切内容与期望输出确切内容的详细信息。i、 e.程序应该做什么。这不是一个好主意。这也是一堵无法阅读的代码墙,块之间没有缩进、注释或空行,即使在我修复了堆栈溢出代码格式之后也是如此。但无论如何,显然你有一个整数数组,而不是数字的ASCII码。这不是一个字符串。重复的-你需要一个
add reg,'0'
,在那里有一些快速的解决方法:将num db 5,4,7,0,1,9,3,6,8,2
更改为num db“5470193682$”
(带引号和美元符号)。您也可以将单个数字排序为ASCII字母。为什么只有我一个人对声称文件不存在的错误消息感到疑惑?“5 4 7 0 1 9 3 6 8 2”
每个值之间有ASCII空格的数组是一个长度的两倍;当前的排序代码希望对连续字节进行排序,而不是对由空格分隔的偶数地址上的字节进行排序。而且它仍然没有$
需要的int21h
/ah=9
终止符。看见您的想法是正确的,但这不是一个替代品。而且,[ax]
不是有效的寻址模式。只有bx | bp+si | di
(或只有1个寄存器而不是2个寄存器的子集)是有效的。您需要添加字节ptr[di],48
,因为这两个操作数都不表示操作数的大小。@PeterCordes感谢您的回答,但我必须澄清,问题是他想打印数字,这是一种更格式化的打印方式,而不是一起打印所有数字,我没有使用$
终止符,因为他可以打印数字,文本会自动打印(当我写这篇文章的时候,我意识到它应该是相反的第一个文本,然后是数字,至于第二个注释,你是100%对的。对的,将缓冲区放在常量字符串之后最有效,这样两个字符串就形成一个大字符串。然后,$
终止符必须放在num
的末尾。或者你的答案是uld建议在循环中一次打印1个数字,而不是在内存中创建字符串(因此您不需要文字空格)。无论如何,OP代码的硬编码长度仍然是9个连续字节。如果您在9个ASCII数字+8个spac的字符串上运行
dec bl
jnz qq
mov BL, 9
qq:
mov cl, BL
mov si,00h
yy:
mov al,num[si]
inc si
cmp al,num[si]
jc xx
mov bh,num[si]
mov num [si],al
dec si
mov num[si],bh
inc si
xx:
dec cl
jnz yy
dec bl
jnz qq
mov dx, 9 ;This is number of elements minus 1
OuterLoop:
mov cx, dx ;This is what actually reduces the task
xor si, si
InnerLoop:
mov al, num[si] ;Reading 2 successive array elements
mov bl, num[si+1]
cmp al, bl ;Comparing as UNsigned numbers
jb NoSwap
mov num[si], bl ;Writing them in reverse order
mov num[si+1], al
NoSwap:
inc si
dec cx
jnz InnerLoop
dec dx
jnz OuterLoop
mov dx, 9 ;This is number of elements minus 1
OuterLoop:
mov cx, dx ;This is what actually reduces the task
lea si, num
InnerLoop:
mov al, [si] ;Reading 2 successive array elements
mov bl, [si+1]
cmp al, bl ;Comparing as UNsigned numbers
jb NoSwap
mov [si], bl ;Writing them in reverse order
mov [si+1], al
NoSwap:
inc si
dec cx
jnz InnerLoop
dec dx
jnz OuterLoop
mov dx, 9 ;This is number of elements minus 1
OuterLoop:
mov cx, dx ;This is what actually reduces the task
lea si, num
InnerLoop:
mov ax, [si] ;Reading 2 successive array elements
cmp al, ah ;Comparing as UNsigned numbers
jb NoSwap
xchg al, ah
mov [si], ax ;Writing them in reverse order
NoSwap:
inc si
dec cx
jnz InnerLoop
dec dx
jnz OuterLoop