【发布时间】:2013-10-13 19:38:19
【问题描述】:
我是汇编语言 (TASM 86x) 的初学者,正在处理我的第一个程序任务。 它本质上并不复杂,但是对于这门语言的新手来说,我很难弄清楚一个简单的冒泡排序。
到目前为止,我只编写过 Witch C++,总体上最难的部分是掌握语法。
任务是获取任何字符串(由用户输入)并按 ASCII 值升序重新排列它(例如,如果您输入 beda,它应该给出 abde)
我不确定我的输出,但这应该在排序完成后出现 我很困惑,因为 它只允许我输入我的字符串,然后退出到命令提示符。无法追踪我在哪里犯了错误,它过早地指向了代码的末尾。
如果有经验丰富的人看看我的代码并指出正确的方向,甚至向新手解释一两件事,我将不胜感激
.model small
.stack 100h
.data
request db 'Enter symbols:', 0Dh, 0Ah, '$'
buffer db 100, ?, 100 dup (0)
.code
start:
MOV ax, @data
MOV ds, ax
; request
MOV ah, 09h
MOV dx, offset request
int 21h
; read string ;reading string to buffer
MOV dx, offset buffer
MOV ah, 0Ah
INT 21h
MOV si, offset buffer
INC si ;going from buffer size to actual length
;of the string
MOV cl, [si] ;string length - loop counter
mov ch, [si] ;string length - loop counter
mov bl, [si] ;bl will be used to reset inner loop counter
DEC cl ;correcting the values, since count goes
dec ch ; from 0 to n-1 instead of 1 to n
inc si ;moving to strings first byte
outer: ;outer loop
dec ch ;decrease counter each pass
jz ending ;when counter reaches 0 end program
mov cl, bl ; reset inner loop counter value
inner: ;inner loop
mov al,byte ptr[si] ;assigning byte(sybol) to al
mov ah, byte ptr[si+1] ;assigning following byte(symbol) to ah
cmp al,ah ;compare the two
jle after_switch ;if the latter's value is higher, no need to switch
开关有问题,不确定它是否能在组装中正常工作
mov bh, al ;main problem-switching values, tried a few different
mov al, ah ;ways of doing it (will show them below), but to no avail
mov ah, bh ;using familiar C syntax
jmp output ;outputing the value
after_switch: ;no switch needed
在外部开关的某个地方应该跳转到输出,但是我想不出在不弄乱序列其余部分的情况下包含它的方法
inc [si] ;going to the next byte
dec cl ;decreasing inner loop counter
jnz inner ;back to the beginning of inner loop until counter reaches 0 (resetting in the outer loop)
jmp outer ;if counter reaches zero, get back to outer
output: ;outputting value from the very first bit
mov ah, 2
mov dl, al ;which after switch is supposed to be stored in al
int 21h
jmp inner ;returning to inner loop to run next course of comparison
ending:
MOV ax, 4c00h
INT 21h
end start
之前尝试过的内循环切换方法
mov al,[si+1]
mov byte ptr[si+1],[si]
mov byte ptr[si], al
返回非法内存引用错误,但是这个问题过去在这个板子上已经回答过了,找到了。
尝试了相同的方法,但使用了 dx:di 寄存器
mov al, byte ptr[si+1]
mov dx:[di], [si]
mov byte ptr[si+1], dx:[di]
mov byte ptr[si], al
返回非法覆盖寄存器错误,在上面找不到任何东西
【问题讨论】:
-
TASM?像TASM这样的俄罗斯学校? :) 关于错误:只有一个指令操作数可以是内存位置。第二个必须注册。一个提示和小广告:如果您是汇编语言的初学者,并且如果您想学习它(不仅仅是为了做作业),请不要使用 TASM 或 MASM! FASM 是今天和明天的汇编器。好吧,NASM 也是如此。 ;)
-
inc [si] ;going to the next byte- 不,您正在增加si现在指向的字节。你只想要inc si。我认为这可能是您问题的很大一部分。唯一可以用作覆盖前缀的寄存器是段寄存器 -dx将不起作用(无论如何你都不想要它)。我非常同意 johnfound 关于汇编程序的看法……但我记得,“TD”,Turbo Debugger,曾经非常好……如果你拥有它并学会使用它,它会对你有很大帮助,我想。 -
我支持 NASM。
-
"只有一个指令操作数可以是内存位置。第二个必须是寄存器。"不一定。尽管在这种情况下它没有用,但
mem, immediate操作数组合也是有效的。就不使用 TASM 而言;使用 TASM 学习 x86 汇编并不难,只要你有一些不错的参考资料(我刚开始时使用 TASM,但当时有可用的教科书使用 TASM 作为代码示例)。 NASM 的优势在于您可以轻松针对 DOS 以外的其他平台,而且它是免费的。 -
您在处理 Pascal 短字符串吗?普通的 C 字符串开头没有长度字节。
标签: sorting assembly x86 bubble-sort tasm