nasm风格的DOS INT 21H功能0AH [英] DOS INT 21H Function 0AH in nasm style
本文介绍了nasm风格的DOS INT 21H功能0AH的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我正在尝试使用nasm重写Peter Abel撰写的"IBM PC组装语言和编程"(第15版)中的汇编程序.这是第144页第8章上给出的有关缓冲输入的演示.
I am trying to use nasm to rewrite assembly programs in "IBM PC ASSEMBLY LANGUAGE AND PROGRAMMING" (15th edition) by Peter Abel. And here is the demo on buffering input, given on the page of 144, Chapter 8.
该程序等效于C编程
char name[20];
scanf("Name?%s", &name);
/*print the input name in the middle of the screen 25 * 80*/
....
我的重写程序是:
;file: A08CTRNM.asm
segment data
paralist:
maxlen: db 20 ;The maximum length of the string will be 20
actulen: resb 1 ;Which character we have inputed now
buffer: times 20 db 0 ;The buffer where the string is buffered
;end of paralist
prompt: db "Name?", "$"
segment code
..start:
mov ax, data
mov ds, ax
mov es, ax
mov ss, ax
mov sp, stacktop
call setCursor
call input
call clearScreen
cmp byte [actulen], 0 ;Name entered?
je exit ;no, exit
call center ;set bell and '$' and center
call displayStr ;Display name
exit:
mov ax, 0x4c00
int 0x21
segment stack stack
resb 64
stacktop:
input:
push ax
push dx
mov ah, 09h ;Print the prompt
mov dx, prompt
int 21h
mov ah, 0ah ;Request keyboard
mov dx, paralist
int 21h
pop dx
pop ax
ret
center:
mov bx, actulen ;Replace ENTER with BELL
mov byte [buffer+bx], BELL ;[buffer+bx] was ENTER, and now is BELL
mov byte [buffer+bx+1], '$' ;Set display delimiter
mov dl, [actulen] ;Locate the center column (40 - strlen / 2)
shr dl, 1 ;devide length by 2
neg dl ;reverse sign
add dl, 40 ;add 40 (DL:DH Colume:Row)
mov dh, 12 ;center row
call setCursor
ret
displayStr:
mov ah, 09h
mov dx, buffer
int 21h
ret
clearScreen:
pusha
mov ax, 0600h
mov bx, 30 ;color attribute
mov cx, LEFT_CORNER
mov dx, RIGHT_CORNER
int 10h
ret
setCursor:
mov ah, 02h
mov bh, 00h
int 10h
ret
我用
$ nasm -fobj A08CTRNM.asm -o a.obj
并在剂量mu下将其与turbo c 2.0中的链接"tlink.exe"链接
And link it with the link "tlink.exe" in turbo c 2.0 under dosemu
c:\tlink a.asm
但是链接器抱怨了什么
Fixup overflow in module A08CTRNM.ASM at CODE:000D, target=000D:0006
Fixup overflow in module A08CTRNM.ASM at CODE:0010, target=0010:0006
Fixup overflow in module A08CTRNM.ASM at CODE:0013, target=0013:0006
Fixup overflow in module A08CTRNM.ASM at CODE:0020, target=0020:0006
当我运行可执行文件"a.exe"时,出现了问题
As I run the executable file "a.exe", something is wrong
c:\a ->
Name?
Invalid Opcode at 00B1 02A9 0202 001B 0000 0000 0000 0000 0000 0000 0000 0000 00
您能告诉我如何修复程序吗?
Can You tell me how to fix the program?
推荐答案
您的堆栈有2个问题.
- 您将
ss
初始化为data
,而不是stack
.解决方案:在mov ss, ax
之前添加 - 您在程序源的中间声明堆栈段,并且不要切换回代码段.这意味着所有从标签
input
开始的代码都将放入堆栈段中.这导致打印错误.解决方案:将堆栈段移至文件底部,或切换回代码段.
mov ax, stack
- You initialize
ss
todata
, notstack
. Solution: Addmov ax, stack
before themov ss, ax
- You declare the stack segment in the middle of your program source, and don't switch back to code segment. This means all the code starting from the label
input
gets put into the stack segment. This is causing the errors that get printed. Solution: move the stack segment to the bottom of the file, or switch back to the code segment.
这篇关于nasm风格的DOS INT 21H功能0AH的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文