Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 有人能解决汇编语言上的显示错误吗_Assembly_X86 16_Tasm - Fatal编程技术网

Assembly 有人能解决汇编语言上的显示错误吗

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

当我用汇编语言编写程序时,更具体地说是.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
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
  • 添加一些解释性评论
草案1:

 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