|
主题 : : 实验10-3编写的程序找不到错误,请教大家(有详细说明) [已解决] |
回复[ 6次 ]
点击[ 599次 ] | |
|
|
|
|
[帖 主]
[ 发表时间:2010-04-27 15:26 ]
[引用]
[回复]
[ top ] | |
荣誉值:4
信誉值:2
注册日期:2008-01-16 11:01 |
显示字符串和除法溢出2个子程序都经过验证的。程序如下:
assume cs:code
data segment
db 10 dup (0)
data ends
stack segment
dw 32 dup (0)
stack ends
code segment
start: mov ax,data
mov ds,ax ;设置ASC码存放空间
mov ax,stack
mov ss,ax
mov sp,64 ;设置栈段
mov si,0 ;设置首地址
mov ax,12666
mov dx,0 ;将数值的低16位送入ax,高16位送入dx,调用子程序转换为ASC码
call dtoc ;调用转换为ASC码子程序
mov dh,8 ;输入行号
mov dl,3 ;输入列号
mov cl,2 ;输入颜色
call show_str ;调用显示字符串子程序
mov ax,4c00h
int 21h
dtoc: push ax
push bx
push cx
push dx
push si
push ds ;将子程序用到的寄存器入栈
mov bx,0 ;设置计数器
d0: mov cx,10 ;除数为10
call divdw ;调用避免除法溢出子程序,商的高16位在dx中,低16位在ax中,余数在cx中
add cx,30h ;余数加30h,变为ASC码
push cx ;将余数ASC码入栈
inc bx ;计数器加1
mov cx,dx ;将商的的高16位移入cx
jcxz d1 ;如果(cx)=0,转移到d1处;如果不是0,向下执行
jmp near ptr d0 ;转移到d0处,继续做除法
d1: mov cx,ax ;将商的的低16位移入cx
jcxz ak ;如果(cx)=0,转移到ak处;如果不是0,向下执行
jmp near ptr d0 ;转移到d0处,继续做除法
ak: mov cx,bx ;将计数器的值存入cx
bk: pop ax ;最后的余数ASC码出栈
mov [si],al ;将余数ASC码存入ds:si处
inc si ;si加1
loop bk ;如果(cx)=0,向下执行;如果不是0,转移到bk处,循环将栈中的余数ASC出栈
mov [si],0 ;设置ASC码结束符,显示字符串子程序根据此符号判断字符串是否结束
pop ds
pop si
pop dx
pop cx
pop bx
pop ax ;将子程序用到的寄存器出栈
ret
show_str: push es
push ds
push si
push ax
push bx
push dx
push cx ;将子程序用到的寄存器入栈
mov al,10
mul dh
mov bx,0b800h
add ax,bx
mov es,ax ;设置行段地址
mov bh,0
mov bl,dl
add bx,bx
sub bx,2 ;设置第一个字符的偏移地址(列地址)
s: mov cl,[si]
mov ch,0
jcxz ok ;如果(cx)=0,转移到标号处;如果不是0,向下执行
pop cx ;将子程序中要用的寄存器内的内容出栈
push cx ;将子程序要用到的寄存器入栈
mov dl,[si]
mov es:[bx],dl ;将字符的ASCII码写入显存
mov es:[bx+1],cl ;将字符的属性写入显存
inc si
add bx,2 ;下一个字符
jmp near ptr s ;跳转到s处执行
ok: pop cx
pop dx
pop bx
pop ax
pop si
pop ds
pop es ;将子程序用到的寄存器出栈
ret
divdw: push bx
push bp
mov bp,ax ;将被除数的低16位存入bp
mov ax,dx ;将被除数X得高16位存入ax,作为H的低16位
mov dx,0 ;将dx置0,作为H的高16位
div cx ;H/N
mov bx,ax ;将H/N的商存入bx
mov ax,bp ;将被除数的低16位存入ax
div cx ;[rem(H/N)*65536+L]/N,商(低16位)在ax中
mov cx,dx ;将余数存入cx
mov dx,bx ;将高16位存入dx
pop bp
pop bx
ret
code ends
end start
没法masm,请问高手问题在哪里? | | |
|
|
|
|
[第1楼]
[ 回复时间:2010-04-28 09:08 ]
[引用]
[回复]
[ top ] | |
荣誉值:62
信誉值:0
注册日期:2009-12-03 13:14 |
google下个masm很快的,加下环境变量就能用了
mov [si],0 ;设置ASC码结束符,显示字符串子程序根据此符号判断字符串是否结束
mov [si],0这句编译报Operand must have size->mov byte ptr[si],0
其他逻辑上的就自己检查下吧^-^ | | |
|
|
|
|
[第2楼]
[ 回复时间:2010-04-28 13:41 ]
[引用]
[回复]
[ top ] | |
荣誉值:4
信誉值:2
注册日期:2008-01-16 11:01 |
楼上兄弟指出的确实是个错误。我不是没有masm,而是用masm汇编源程序后,如果源程序有错误,就不会产生obj文件,没有任何说明,直接退出masm。请问如何看到编译报错? | | |
|
|
|
|
[第3楼]
[ 回复时间:2010-04-28 16:10 ]
[引用]
[回复]
[ top ] | |
荣誉值:62
信誉值:0
注册日期:2009-12-03 13:14 |
编译器错误就在命令行下方,不要说你看不懂E文=.=
Operand must have size就是masm5.0报的 | | |
|
|
|
|
[第4楼]
[ 回复时间:2010-04-29 09:02 ]
[引用]
[回复]
[ top ] | |
荣誉值:4
信誉值:2
注册日期:2008-01-16 11:01 |
看不到任何东西。我运行masm.exe文件,进入dos环境,输入路径:…\...\...\*.asm;,如果程序正确,会生成*.obj文件;如果程序不正确,则dos屏幕一闪就不见了,也不会生成任何文件。故程序有错误,我看不到任何错误提示。
非常感激versaariel。将mov [si],0改成mov ax,0 / mov [si],ax,程序顺利通过。
另外,我觉得如果需要显示的数字超过65536,则程序要改动2处:
第一处:
data segment
db 10 dup (0)
dd 5937000 ;新加入的句子,为要显示的数字
data ends
第二处:将
mov ax,12666
mov dx,0 ;将数值的低16位送入ax,高16位送入dx,调用子程序转换为ASC码
改成:
Mov ax,ds:[10] ;将数值的低16位送入ax
Mov dx,ds:[12] ;将数值的高16位送入dx
则超过65536的数字也能顺利显示了。
还有个问题,如果程序改成如下:
data segment
db 10 dup (0)
data ends
data2 segment
dd 5937000
data2 ends
.
.
.
Mov ax,data
Mov ds,ax
Mov ax,ds:[?]
Mov dx,ds:[?+2]
那么,?处填的数字是什么。我试过,填10是错误的。 | | |
|
|
|
|
[第5楼]
[ 回复时间:2010-04-29 11:12 ]
[引用]
[回复]
[ top ] | |
荣誉值:62
信誉值:0
注册日期:2009-12-03 13:14 |
1.恩,确实试了下你的方法,好象你那样看不到编译结果,原因就不说了,以后你会知道^-^
2.
--------------------引用-------------------------------
我运行masm.exe文件,进入dos环境,输入路径:…\...\...\*.asm
-------------------------------------------------------
换个方法,论坛里有教过的
我的电脑->属性->高级->环境变量->用户变量中找到path加入masm.exe的路径,就可以在任意路径下编译文件了.比如我加的是;E:\Program Files\masm5.0(前面那个;一定要加)
编译的时候:win+r->cmd->定位到你程序文件(test.asm)的路径,不要说你不会用cd命令,
最后masm test.asm就行了
3.有时间多看看论坛里的旧帖子,都很好的^-^ | | |
|
|
|
|
[第6楼]
[ 回复时间:2010-05-10 13:59 ]
[引用]
[回复]
[ top ] | |
荣誉值:4
信誉值:2
注册日期:2008-01-16 11:01 |
此贴由 贴主 于 [ 2010-05-10 13:59 ] 结贴。 结贴原因:问题已解决 | | |
|