我是装配新手,我有一个奇怪的错误。我使用286和TASM汇编程序。我在dosbox上模拟我的程序。我的程序只是要求用户输入一个字符串,然后输出相同的字符串。这是我的全部代码:
.286
.model huge
.stack 300h
.CODE
start:
lea bx, x
push bx
call gets ; Read the string
lea bx, x
push bx
call puts ; Output the string
jmp terminate ; End it
; ---------- char getche(void) ----------
getche:
; Reads a character from keyboard and output into dl register
push ax ; push stacks we use
mov ah, 1h ; get character and echo
int 21h
mov dl, al ; output the character into dl
pop ax ; pop the stacks
ret ; return
; ---------- end of function ----------
; ---------- void putch(char c) ----------
putch:
; Print character into screen
push ax ;Push the stacks we use
push bx
push dx
push bp
mov bp, sp ; Load the character
mov bx, [bp+10]
mov dl, [bx] ; store the argument into dx
mov ah, 2h ; print the character
int 21h
pop bp ; Pop all the stacks we used
pop dx
pop bx
pop ax
ret 2 ; return
; ---------- end of function ----------
; ---------- void puts(char *p) ----------
puts:
; Prints string to the console
push bp ; Push the stacks
push bx
push cx
mov cl, 0 ; The null character
mov bp, sp
mov bx, [bp+8] ; Load the adress of beginning of the string
.pts_loop:
cmp [bx], cl
jz .pts_exit ; Jump if it is the null character
push bx
call putch ; Print the character
inc bx
jmp .pts_loop
.pts_exit:
pop cx ; Pop the stacks
pop bx
pop bp
ret 2
; ---------- end of function ----------
; ---------- void gets(char *p) ----------
gets:
; Reads a string from keyboard
push bp ; Push stacks
push bx
push cx
mov bp, sp ; Load the address
mov bx, [bp+8]
mov cl, 13
.gts_loop:
call getche
mov [bx], dl
inc bx
cmp dl, cl ; Check if it is the 'Enter' key
jnz SHORT .gts_loop
mov [bx], 0 ; Add the null
pop cx ; Pop stacks
pop bx
pop bp
ret 2
; ---------- end of function ----------
terminate:
mov ah, 4ch ; terminate the program
mov al, 00
int 21h
.DATA
x db "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" ; Doesn't matter what's inside
END start
如果我的字符串的长度是< = 10.它将终止没有问题。但是,如果是> 10然后它崩溃了。我使用了调试,我注意到在执行过程中一切正常,直到它终止。当我执行中断时,它会跳转到全部为0的地方并且它会永远运行...我想我的字符串可能会覆盖一些重要的数据。我试图将.DATA从我的代码开始移动到最后,但它并没有多大帮助。有什么建议吗?
编辑:我将mov cl, 13
更改为mov cl, 0
。我将堆栈增加到200h甚至300h,但问题仍然存在。
答案 0 :(得分:1)
您永远不会设置DS / ES。
mov ax,.DATA ; <-- Syntax used depends on assembler used!!!
mov ds,ax
mov es,ax
或者完全删除 .DATA 指令。这会将字符串 x 放在 .CODE 部分中,所以这次使用类似
的代码设置DS / ESstart:
mov ax,cs
mov ds,ax
mov es,ax
当处理超过10个字符时问题首先从DOS函数4Ch开始的事实源于在ProgramSegmentPrefix DOS中的偏移量10保留一些非常重要的中断向量的事实。这些都是由于没有初始化DS而被覆盖。当EXE启动时,DS寄存器指向PSP。
答案 1 :(得分:1)
您忘记初始化DS
:
...
.CODE
start:
mov ax, @data
mov ds, ax
...
对于MS-DOS程序,您必须初始化DS 始终!
我测试了它,现在你的代码适用于我。
顺便说一句:
如果.model huge
没有特殊原因,请避免使用!使用.model small
。
更改
mov [bx], 0 ; Add the null ; *Warning* Argument needs type override
到
mov byte ptr [bx], 0 ; Add the null