注册 登录
编程论坛 汇编论坛

麻烦请教一下,为什么这个代码会出现这种问题

oped02 发布于 2022-11-13 13:15, 2348 次点击
程序代码:
data    segment
    Pgsize        dw    ?
    buf_size    db    80
    s_buf        db    ?
    buf        db    200    dup(?)
    cur        dw    ?
    handle        dw    ?
    mess_getname    db    0dh,0ah,"    Please input filename:$"
    mess_err1    db    0ah,0dh,"    Illegal filename! $"
    mess_err2    db    0ah,0dh,"    File not found ! $"
    mess-err3    db    0ah,0dh,"    File read error ! $”
    mess-psize    db    0ah,0dh,
"    Page Size : $”
    crlf        db    0ah,0dh,"$"
    mess_star    db    0ah,0dh,"**************************"
            db    0ah,0dh,"$"
data    ends


code segrnent
    assume ds:data,cs:code
    main proc far
start:
    push    ds
    sub    ax,ax
    push    ax
    mov    ax,data
    mov    ds,ax

    mov    PgSize,12    ;Each page 12 lines.
    mov    cur,200        ;File data buffer is empty.
    call    getline        ; Get file name.
    call    openf        ; open the file , (ax)=0 means no such file
    or    ax,ax
    jnz    display
    mov    dx,offset mess_err2
    mov    ah,09h
    int    21h        ;(ax)=0 : no such file.
    jmp    file_end

display:
    mov cx,PgSize

show_page:
    call    read_block        ; read a line from handle to buf
    or    ax,ax
    jnz    next2
    mov    dx,offset mess_err3
    mov    ah,09h
    int    21h            ;(ax)=0 : error in read.
    jmp    file_end

next2:
    call    show_block        ; display a line in buf , (bx) returned o
                    ; means that the file reach its end.
    or    bx,bx
    jz    file_end        ;(bx)=0: at the end of file.
    or    cx,cx
    jnz    show_page        ;(cx)<>0; not the last line of a page.
    mov    dx,offset mess_star
    mov    ah,09h
    int    21h            ;At the end of a page,print a line of * .
    ; the current page has been on screen,and followed by a line of stars.
    ;the following part get the command from keyboard:
wait-space:
    mov    ah,1
    int    21h
    cmp    ai," "
    jnz    psize
    jmp    display
psize:
    cmp    al,"p"
    jnz    wait-space
    call    change_psize
here:
    mov    ah,1
    int    21h
    cmp    al," "
    jnz    here            ;stick here to wait for space.
    jmp    display

file_end:
    ret
main endp
;****************************************************************
;
****************************************************************
change_psize    proc    near
    push    ax
    push    bx
    push    cx
    push    dx
    mov    dx,offset mess_psize
    mov    ah ,09h
    int    21h            ;print the promt line
    mov    ah,01
    int    21h            ;get the new num. of page size.
    cmp    al,0dh
    jz    illeg
    sub    al,"0"
    mov    cl,al

getp:
    mov    ah,1
    int    21h
    cmp    al,0dh
    jz    pgot
    sub    al,"0"
    mov    dl,al
    mov    al,cl
    mov    cl,dl            ;exchange al and cl.
    mov    bl,10
    mul    bl
    add    cl,al
    jmp    getp

pgot:
    mov    dl,0ah
    mov    ah,2
    int    21h            ;output Oah to complete the RETURN.
    cmp    cx,0
    jle    illeg
    cmp    cx,24
    jg    illeg
    mov    PgSize,cx        ; be sure the new page size in (o..24) region.

illeg:
    mov    dl,0ah
    mov    ah,2
    int    21h            ;output Oah to complete the RETURN.
    pop    dx
    pop    cx
    pop    bx
    pop    ax
    ret
change_psize endp
;****************************************************************
;
****************************************************************
openf    proc    near
    push    bx
    push    cx
    push    dx
    mov    dx,offset buf
    mov    al,0
    mov    ah,3dh
    int    21h
    mov    handle,ax
    mov    ax,1
    jnc    ok
    mov    ax , 0

ok:
    pop    dx
    pop    cx
    pop    bx
    ret
openf    endp
;****************************************************************
;
****************************************************************
getline    proc    near
    push    ax
    push    bx
    push    cx
    push    dx
    mov    dx,offset mess_getname
    mov    ah,09h
    int    21h            ; promt user to input file name.
    mov    dx,offset buf_size
    mov    ah,0ah
    int    21h            ; function call of buffer input.
    mov    dx,offset crlf
    mov    ah,09h
    int    21h            ; return.
    mov    bl,s_buf
    mov    bh,0
    mov    [buf+bx],0        ;put 0 into the end of file name
    pop    dx
    pop    cx
    pop    bx
    pop    ax
    ret
getline endp
;****************************************************************
;
****************************************************************
read_block    proc    near
    push    bx
    push    cx
    push    dx
    cmp    cur,200
    jnz    back
; if no more chars in buf can be displayed
;
then read another 200 chars ;
    mov    cx,200
    mov    bx , handle
    mov    dx , offset buf
    mov    ah , 3fh
    int    21h
    mov    cur,0
    mov    ax,1
    jnc    back
    mov    cur,200
    mov    ax ,0
back:
    pop    dx
    pop    cx
    pop    bx
    ret
read_block endp
;****************************************************************
;
****************************************************************
show_block    proc    near
    push    ax
    push    dx
    mov    bx,cur

loop1:
    cmp    bx,200
    jl    lp
    jmp    exit            ; if buf is empty then return.

lp:
    mov    dl,buf[bx]        ;else show the currnet char.
    cmp    dl,1ah            ; search the file end
    jz    exit_eof
    inc    bx
    inc    cur
    mov    ah,02
    int    21h
    cmp    dl,0ah
    jz    exit_ln            ;if the char shown is RETURN,
                    ;then exit. A line has been on screen.
    jmp    loop1
exit_eof:
    mov    bx,0

exit_ln:
    dec    cx
exit:
    pop    dx
    pop    ax
    ret
show_block endp
;****************************************************************
code ends
end start
7 回复
#2
oped022022-11-13 13:17
就是当文件内只有一行数据时或者输入的文件名只有一行是,会无限循环输出
#3
Valenciax2022-11-14 05:03
先不论楼主的问题,这个代码根本不能通过编译,错误如下


1.
code segrnent -> code segment
这是串错

2.
mess-err3    db    0ah,0dh,"    File read error ! $”
mess-psize    db    0ah,0dh,"    Page Size : $”

'-'(减号),不能作名称,应该用'_'(下线)
字串结束的双引号用了全形的[ ” ]  , 应该是半形的 [ " ]

mess_err3    db    0ah,0dh,"    File read error ! $"
mess_psize    db    0ah,0dh,"    Page Size : $"

其怪的是,data段里是mess-err3(减号),代码段卻是mess_err3(下线),'错'不应该一直错到底吗?

3.
wait-space:
jnz wait-space

同上,'-'(减号),不能作名称或Label名,应该用'_'(下线)

4.
cmp    ai," "
ai应该是AL (AX寄存器的低位)



若楼主是自己写的代码,这些错误应该不存在,因为编译不通过就不会产生EXE,也就是不会有运行结果.
估计是网上现存的代码(可能只有图或不能覆制)和运行档,楼主自己敲代码贴上来,难免有敲错,但自己不先编译一遍就有点说不过去....



至于楼的问题,有空再看.......



#4
Valenciax2022-11-14 06:45
不知道题目或者这些代码的目的,约略看了一下,似乎是读入一个档,然后输出一个定量长度,按一下空白再显示...
代码是很老式的写法,也比较累赘,就以上述的自的,'输出一个用户指定的档',其实可以精简一些,若楼主有附加要求,可以自行修改.

以下就原代码精简的结果.
程序代码:

readsize equ 1600        ;每次读入长度
ScreenHandle equ 2        ;屏幕句柄,handle=2

data segment
    Pgsize    dw    ?
    buf_size    db    80
    s_buf       db    ?
    buf            db    readsize   dup(?)
    ReadLength  dw    ?        ;实际读入长度
    handle      dw    ?
    mess_getname db   0dh,0ah,"    Please input filename:$"
    mess_err2    db   0ah,0dh,"  File not found ! $"
    mess_err3    db   0ah,0dh,"    File read error !$"
    ctrf         db   0ah,0dh,'$'
data ends

code segment
    assume ds:data,cs:code
start:
    mov    ax,data
    mov    ds,ax
    call   getline    ; Get file name.
    mov    dx,offset ctrf
    mov    ah,9h
    int    21h
    call    openf       ; open the file , (ax)=0 means no such file
    jnc    display    ;没有错则跳
    mov    dx,offset mess_err2
err:
    mov    ah,09h
    int    21h        ;(ax)=0 : no such file.
    jmp    file_end
display:
    mov    cx,readsize        ;cx=读入长度
    call   read_block            ;read a line from handle to buf
    or     ax,ax        ;比较实际读入长度
    jz        file_end        ;若=0,则已读完,离开
    mov    dx,offset mess_err3
    jc     err            ;离开
    call   show_block            ; display a line in buf , (bx) returned o
    mov    ah,0            ;读任意键
    int    16h
    cmp    ReadLength,0        ;是否已读完
    jnz    display        ;读入长度不等于0,再来
file_end:
    mov ax,4c00h        ;返回dos
    int 21h   
;****************************************************************
openf:
    mov    dx,offset buf
    mov    al,0
    mov    ah,3dh
    int    21h
    mov    handle,ax
    ret
;****************************************************************
getline:
    mov    dx,offset mess_getname
    mov    ah,09h
    int    21h            ; promt user to input file name.
    mov    dx,offset buf_size
    mov    ah,0ah
    int    21h            ; function call of buffer input.
    mov    bl,s_buf
    mov    bh,0
    mov    [buf+bx],0        ;put 0 into the end of file name
    ret
;****************************************************************
read_block:
    mov    bx , handle
    mov    dx , offset buf
    mov    ah , 3fh
    int    21h
    jnc    back
    ret
back:
    mov  ReadLength,ax
@@:
    ret
;****************************************************************
show_block:
    mov     bx,ScreenHandle    ;屏幕Handle=2,相当于写入(输出)到屏幕
    mov     cx,ReadLength     ;实际读入长度   
    mov     dx,offset Buf   
    mov     ah,40h        ;写出Handle
    int     21h
    ret
;****************************************************************
code ends
end start


以下是执行
只有本站会员才能查看附件,请 登录
#5
oped022022-11-14 17:22
回复 3楼 Valenciax
不好意思不好意思,我上错代码了,改好的代码在另一个盘里,我打开的文件夹里默认还是之前的
太不好意思了
#6
oped022022-11-14 17:25
程序代码:
data    segment
    Pgsize        dw    ?
    buf_size    db    80
    s_buf        db    ?
    buf        db    200    dup(?)
    cur        dw    ?
    handle        dw    ?
    mess_getname    db    0dh,0ah,"    Please input filename:$"
    mess_err1    db    0ah,0dh,"    Illegal filename! $"
    mess_err2    db    0ah,0dh,"    File not found ! $"
    mess_err3    db    0ah,0dh,"    File read error ! $"
    mess_psize    db    0ah,0dh,"    Page Size : $"
    crlf        db    0ah,0dh,"$"
    mess_star    db    0ah,0dh,"**************************"
            db    0ah,0dh,"$"
data    ends


code segment
    assume ds:data,cs:code
    main proc far
start:
    push    ds
    sub    ax,ax
    push    ax
    mov    ax,data
    mov    ds,ax

    mov    PgSize,12    ;Each page 12 lines.
    mov    cur,200        ;File data buffer is empty.
    call    getline        ; Get file name.
    call    openf        ; open the file , (ax)=0 means no such file
    or    ax,ax
    jnz    display
    mov    dx,offset mess_err2
    mov    ah,09h
    int    21h        ;(ax)=0 : no such file.
    jmp    file_end

display:
    mov cx,PgSize

show_page:
    call    read_block        ; read a line from handle to buf
    or    ax,ax
    jnz    next2
    mov    dx,offset mess_err3
    mov    ah,09h
    int    21h            ;(ax)=0 : error in read.
    jmp    file_end

next2:
    call    show_block        ; display a line in buf , (bx) returned o
                    ; means that the file reach its end.
    or    bx,bx
    jz    file_end        ;(bx)=0: at the end of file.
    or    cx,cx
    jnz    show_page        ;(cx)<>0; not the last line of a page.
    mov    dx,offset mess_star
    mov    ah,09h
    int    21h            ;At the end of a page,print a line of * .
    ; the current page has been on screen,and followed by a line of stars.
    ; the following part get the command from keyboard:
wait_space:
    mov    ah,1
    int    21h
    cmp    al," "
    jnz    psize
    jmp    display
psize:
    cmp    al,"p"
    jnz    wait_space
    call    change_psize
here:
    mov    ah,1
    int    21h
    cmp    al," "
    jnz    here            ;stick here to wait for space.
    jmp    display

file_end:
    ret
main endp
;****************************************************************
;
****************************************************************
change_psize    proc    near
    push    ax
    push    bx
    push    cx
    push    dx
    mov    dx,offset mess_psize
    mov    ah ,09h
    int    21h            ;print the promt line
    mov    ah,01
    int    21h            ;get the new num. of page size.
    cmp    al,0dh
    jz    illeg
    sub    al,"0"
    mov    cl,al

getp:
    mov    ah,1
    int    21h
    cmp    al,0dh
    jz    pgot
    sub    al,"0"
    mov    dl,al
    mov    al,cl
    mov    cl,dl            ;exchange al and cl.
    mov    bl,10
    mul    bl
    add    cl,al
    jmp    getp

pgot:
    mov    dl,0ah
    mov    ah,2
    int    21h            ;output Oah to complete the RETURN.
    cmp    cx,0
    jle    illeg
    cmp    cx,24
    jg    illeg
    mov    PgSize,cx        ;be sure the new page size in (o..24) region.

illeg:
    mov    dl,0ah
    mov    ah,2
    int    21h            ;output Oah to complete the RETURN.
    pop    dx
    pop    cx
    pop    bx
    pop    ax
    ret
change_psize endp
;****************************************************************
;
****************************************************************
openf    proc    near
    push    bx
    push    cx
    push    dx
    mov    dx,offset buf
    mov    al,0
    mov    ah,3dh
    int    21h
    mov    handle,ax
    mov    ax,1
    jnc    ok
    mov    ax,0

ok:
    pop    dx
    pop    cx
    pop    bx
    ret
openf    endp
;****************************************************************
;
****************************************************************
getline    proc    near
    push    ax
    push    bx
    push    cx
    push    dx
    mov    dx,offset mess_getname
    mov    ah,09h
    int    21h            ; promt user to input file name.
    mov    dx,offset buf_size
    mov    ah,0ah
    int    21h            ; function call of buffer input.
    mov    dx,offset crlf
    mov    ah,09h
    int    21h            ; return.
    mov    bl,s_buf
    mov    bh,0
    mov    [buf+bx],0        ;put 0 into the end of file name
    pop    dx
    pop    cx
    pop    bx
    pop    ax
    ret
getline endp
;****************************************************************
;
****************************************************************
read_block    proc    near
    push    bx
    push    cx
    push    dx
    cmp    cur,200
    jnz    back   
    ;if no more chars in buf can be displayed then read another 200 chars ;
    mov    cx,200
    mov    bx , handle
    mov    dx , offset buf
    mov    ah , 3fh
    int    21h
    mov    cur,0
    mov    ax,1
    jnc    back
    mov    cur,200
    mov    ax ,0
back:
    pop    dx
    pop    cx
    pop    bx
    ret
read_block    endp
;****************************************************************
;
****************************************************************
show_block    proc    near
    push    ax
    push    dx
    mov    bx,cur

loopl:
    cmp    bx,200
    jl    lp
    jmp    exit            ; if buf is empty then return.

lp:
    mov    dl,buf[bx]        ;else show the currnet char.
    cmp    dl,1ah            ; search the file end
    jz    exit_eof
    inc    bx
    inc    cur
    mov    ah,02
    int    21h
    cmp    dl,0ah
    jz    exit_ln            ;if the char shown is RETURN,
                    ;then exit. A line has been on screen.
    jmp    loopl

exit_eof:
    mov    bx,0
    mov    bx,0
exit_ln:
    dec    cx
exit:
    pop    dx
    pop    ax
    ret
show_block endp
;****************************************************************
code ends
end start

为了发帖的严谨性,这是我之前敲好并修改之后的代码
#7
oped022022-11-14 17:27
回复 4楼 Valenciax
这些代码的来源都是《IBM-PC汇编语言程序设计 实验教程》这本书上的,我们现在正在学习
#8
Valenciax2022-11-15 03:45
回复 6楼 oped02
这里是欠缺一个'是否读完'的判别,可以在data段加一条
readlength dw  ?

另外,修改代码
1.
show_page:
    call    read_block      ; read a line from handle to buf
    cmp   readlength,0        ;加入,比较读入长度
    jz    file_end          ;加入,若读入长度=0,表示已读完,可以离开


2.
    mov    ah , 3fh
    int    21h
    mov    readlength,ax ;加入,ax是实际读入长度,供上面判别
1