一个小小的汇编程序,烦请各位高手小看一下帮忙解决解决啊(急用)

sunlixin723 2009-04-24 10:52:34
我们刚学汇编,所以一些指令啊,格式啊都还不太会用,问老师他还不怎么愿意告诉我,所以还烦请大家帮帮忙啊!
下面的程序就是在BUFFER中找到最小的那个数,然后输出,我汇编了一下,没错,可就是运行不了,那个黑框框一蹦出来就有回去了,这是怎么回事呢?呵呵
这是别人编的,我也找不出来有什么错误,只是看出点儿小问题
;****************************************************
DATA SEGMENT
BUFFER DB 2,4,6,1,8 ;这几个数是不是输不出来呀?
COUNT EQU $-BUFFER ;BUFFER 前不加OFFSET行不行呀,意思会变吗?
MAX DW ? ;这句是不是不需要啊?
DATA ENDS
:**************************************************
STACK SEGMENT PARA STACK 'STACK' ;这个段是不是不需要啊?
DB 64 DUP(?)
TOP EQU $-STACK
STACK ENDS
;***************************************************
CODE SEGMENT
MAIN PROC FAR
ASSUME CS:CODE,SS:STACK,DS:DATA
START:PUSH DS
MOV AX,0 ;与SUB AX,AX 有什么区别吗?
PUSH AX
MOV AX,DATA
MOV DS,AX
MOV AX,TOP ;这两句有必要吗?
MOV SP,AX
MOV CX,COUNT
LEA BX,BUFFER ;这个对吗,是不是应该换成MOV BX,0
MOV Al,BUFFER[BX]
INC BX
DEC CX
AGAIN:
CMP Al,BUFFER[BX]
JNGE NEXT
MOV Al,BUFFER[BX]
NEXT:
INC BX
DEC CX
JNZ AGAIN

MOV AH,2
MOV DL,AL
INT 21H
mov ax, 4c00h ;有RET这两句是不是就不用了呀?
int 21h
RET
MAIN ENDP
CODE ENDS
;*************************************************
END START


...全文
193 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
光宇广贞 2009-04-28
  • 打赏
  • 举报
回复
恭喜啊……结贴吧……
sunlixin723 2009-04-27
  • 打赏
  • 举报
回复
谢谢你呀,呵呵,换了个环境,还真的运行了,很好,太感谢你了
sunlixin723 2009-04-26
  • 打赏
  • 举报
回复
这个看不懂耶,运行也没什么结果,还是我用的那个开发环境不受用?
sunlixin723 2009-04-26
  • 打赏
  • 举报
回复
真的很感谢你,可是你的程序我还是运行不出什么结果啊,用命令行也是,到底怎么回事啊
rqshi0315 2009-04-26
  • 打赏
  • 举报
回复
楼主说那个程序运行不行啊。

我给你的可是在自己机子上实验了啊!!!!!!!
光宇广贞 2009-04-26
  • 打赏
  • 举报
回复
学校的应该都是MASM做教学平台的吧,相当于TURBO C之于C教学……

否则你的开发环境是……

AT&T 还是 INTEL 的?……不至于专业化到如此吧……

看代码风格也是 MASM,也只有 MASM 可以跑这种写法的代码。

那个 Top 换成立即数吧,没什么意义。

还有 STACK 段没有必要,既然是MASM的,那么你删了它不做定义,编译器也会自动给你的程序配一个缺省的堆栈段的。上学那时后期写MASM,我就不再写STACK段了,当然了,这不是个好习惯。换别的平台,写不写在于编译器的能力。

mov ax, 0,这是清零操作,有很多种方法,比如 int i = 0; 和 int i; i = i - i; 就是你所问的两种情况,你说哪种合法呢? SUB 来清零也是可以的,不过不合规范。一条ASM指令需要若干CPU周期,不是原子操作(查操作系统概念),SUB要费更多的周期,用SUB来清零是危险的。

清零最好用 XOR AX, AX 指令。安全而且高效,这是规范作法。

LEA BX, BUFFER 相当于 MOV BX, OFFSET BUFFER,别混了,效率上早期是 MOV 要高,不过现在的 CPU 好像二者差不多了。而在 VC++ 里面内联汇编的时候,MOV 写法还是非法的……所以还是习惯于 LEA 命令吧。

规范写法应该是 LEA BX, [BUFFER],不加也可以,不过不合法。

最后 4C00 的中断,功用是将CPU的控制权由程序交还给操作系统,而RET则是要清理堆栈。二者可完全不是一回事儿!你把中断行删除了,可能会死机……当然了,你肯定用的是 WINDOWS 系统,用保护模式,况且是在MASM下运行程序,不会有什么问题,要是在老的16位DOS下使用实模式,那系统就死了……问题很严重的……

PS,做为学计算机的女生,看照片还算是漂亮的……
sunlixin723 2009-04-25
  • 打赏
  • 举报
回复
什么是输出屏蔽啊?我在命令提示符中输入,总是要换行的嘛,我一按回车就一个error,到底要怎么输入啊?问题很白痴,呵呵,见谅啊
BAYNPU 2009-04-25
  • 打赏
  • 举报
回复
对不起,你这个程序没有输出屏蔽的功能,只能在DEBUG调试跟踪找出比较后最小的数.
BAYNPU 2009-04-25
  • 打赏
  • 举报
回复
data segment
buffer dw 2,4,6,1,8
MAX dw 10 dup(?)
printn db 30 dup(?),13,10,'$'
data ends
code segment
assume cs:code,ds:data
start:
push ds
sub ax,ax
push ax
mov ax,data
mov ds,ax
mov si,5
mov bx,0
loopp:
mov ax,buffer[bx]
mov dx,0
mov cx,5
lea di,buffer
next:
cmp ax,[di]
jg no_count
inc dx
no_count:
add di,2
loop next
mov MAX[bx],dx
dec dx
mov di,dx
add di,dx
add di, dx
mov cl,10
div cl
add al,30H
add ah,30H
mov printn[di],al
inc di
mov printn[di],ah
inc di
mov printn[di],20H
add bx,2
dec si
jne loopp
lea dx,printn
mov ah,09
int 21H
mov ax,4c00h
int 21h
code ends
end start
rqshi0315 2009-04-25
  • 打赏
  • 举报
回复
晕,把程序拷错了。修改代码如下:

;****************************************************
DATA SEGMENT
BUFFER DB 2,4,6,1,8
COUNT EQU $-BUFFER
DATA ENDS
;**************************************************

;***************************************************
CODE SEGMENT
MAIN PROC FAR
ASSUME CS:CODE,DS:DATA
START:


MOV AX,DATA
MOV DS,AX
MOV CX,COUNT
lea Bx,BUFFER

MOV Al,[BX]
INC BX
DEC CX
AGAIN:
CMP Al,[BX]
JNGE NEXT
MOV Al,[BX]
NEXT:
INC BX
DEC CX
JNZ AGAIN

MOV AH,2
MOV DL,AL
INT 21H
mov ax, 4c00h
int 21h
MAIN ENDP
CODE ENDS
;*************************************************
END START
rqshi0315 2009-04-25
  • 打赏
  • 举报
回复
恭喜楼主,这个程序不是你写的。 代码乱的一踏。针对你的提问回答如下。



;****************************************************
DATA SEGMENT
BUFFER DB 2,4,6,1,8 ;这几个数是不是输不出来呀? *********在内存中,想输出来必须要写代码
COUNT EQU $-BUFFER ;BUFFER 前不加OFFSET行不行呀,意思会变吗?***********如果你用masm 好像不行,offset指出是偏移地址。
MAX DW ? ;这句是不是不需要啊? ******************在此代码中没有用到,可不要
DATA ENDS
;**************************************************
STACK SEGMENT PARA STACK 'STACK' ;这个段是不是不需要啊? **********需要,因为代码中用到了堆栈. 可是这个程序确实不需要堆栈。程序修改一下

;可以把他去掉了
DB 64 DUP(?)
TOP EQU $-STACK
STACK ENDS
;***************************************************
CODE SEGMENT
MAIN PROC FAR
ASSUME CS:CODE,SS:STACK,DS:DATA
START:PUSH DS
MOV AX,0 ;与SUB AX,AX 有什么区别吗?************都可以
PUSH AX
MOV AX,DATA
MOV DS,AX
MOV AX,TOP ;这两句有必要吗?******************top是内存中的数据,他表示栈顶,这两句是让sp 指向栈顶
MOV SP,AX
MOV CX,COUNT
lea Bx,BUFFER ;这个对吗,是不是应该换成MOV BX,0 **************************你说的完全正确,虽然程序能正确运行,但是因为Buffer的
;偏移恰好是0
MOV Al,BUFFER[BX]
INC BX
DEC CX
AGAIN:
CMP Al,BUFFER[BX]
JNGE NEXT
MOV Al,BUFFER[BX]
NEXT:
INC BX
DEC CX
JNZ AGAIN

MOV AH,2
MOV DL,AL
INT 21H
mov ax, 4c00h ;有RET这两句是不是就不用了呀? ********不是这样,这两句是将程序 返回到dos系统,和ret 不同。
int 21h
ret
MAIN ENDP
CODE ENDS
;*************************************************
END START

修改一下:
;****************************************************
DATA SEGMENT
BUFFER DB 2,4,6,1,8 ;这几个数是不是输不出来呀? *********在内存中,想输出来必须要写代码
COUNT EQU $-BUFFER ;BUFFER 前不加OFFSET行不行呀,意思会变吗?***********如果你用masm 好像不行,offset指出是偏移地址。
MAX DW ? ;这句是不是不需要啊? ******************在此代码中没有用到,可不要
DATA ENDS
;**************************************************
STACK SEGMENT PARA STACK 'STACK' ;这个段是不是不需要啊? **********需要,因为代码中用到了堆栈. 可是这个程序确实不需要堆栈。程序修改一下

;可以把他去掉了
DB 64 DUP(?)
TOP EQU $-STACK
STACK ENDS
;***************************************************
CODE SEGMENT
MAIN PROC FAR
ASSUME CS:CODE,SS:STACK,DS:DATA
START:PUSH DS
MOV AX,0 ;与SUB AX,AX 有什么区别吗?************都可以
PUSH AX
MOV AX,DATA
MOV DS,AX
MOV AX,TOP ;这两句有必要吗?******************top是内存中的数据,他表示栈顶,这两句是让sp 指向栈顶
MOV SP,AX
MOV CX,COUNT
lea Bx,BUFFER ;这个对吗,是不是应该换成MOV BX,0 **************************你说的完全正确,虽然程序能正确运行,但是因为Buffer的
;偏移恰好是0
MOV Al,BUFFER[BX]
INC BX
DEC CX
AGAIN:
CMP Al,BUFFER[BX]
JNGE NEXT
MOV Al,BUFFER[BX]
NEXT:
INC BX
DEC CX
JNZ AGAIN

MOV AH,2
MOV DL,AL
INT 21H
mov ax, 4c00h
int 21h

MAIN ENDP
CODE ENDS
;*************************************************
END START
你可以查看一下我整理的汇编格式外壳:
http://blog.csdn.net/rqshi0315/archive/2009/03/25/4022494.aspx


关于如何查看最后运行结果的问题。 找到程序 所在的文件夹,然后在cmd下运行就行了。
Windows开始图标——>运行——>cmd——>cd 文件所在文件夹( 路径)--->文件名.exe 就OK了。
不过显示出来的不是你想像中的最新值1 ,而是1所代表的码值。应该是个笑脸。
sunlixin723 2009-04-24
  • 打赏
  • 举报
回复
说实话,我们之前一直在学一些理论的东西,当然上课也听不懂,从来都没实践过,有人让我帮忙改程序,我这才开始翻书。看得乱七八糟。我是在ASM的一个集成开发环境中运行的,要在命令提示符中运行吗?
书上没有啊,可能是我看得不细吧,我再翻翻,呵呵
可是MAX没有用啊,结果不就在AL中吗,直接输出AL不就行吗
谢谢你呀
小赌移情 2009-04-24
  • 打赏
  • 举报
回复
你是直接用鼠標點你的.exe文件嗎?
要在command中用命令行運行的.

你問的這些問題都可以在書上找到答案啊.

MAX在此是用來保存結果的, 當然要.
STACK段當然要,

你還是先用命令行運行一下你的程序, 再把你有疑問的地方自己改一下,debug一下, 應該會有答案. 不然別人說了你也不記心.

21,459

社区成员

发帖
与我相关
我的任务
社区描述
汇编语言(Assembly Language)是任何一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。
社区管理员
  • 汇编语言
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧