nasm风格的DOS INT 21H功能0AH [英] DOS INT 21H Function 0AH in nasm style

查看:377
本文介绍了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下将其与tu​​rbo 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个问题.

  1. 您将ss初始化为data,而不是stack.解决方案:在mov ss, ax
  2. 之前添加mov ax, stack
  3. 您在程序源的中间声明堆栈段,并且不要切换回代码段.这意味着所有从标签input开始的代码都将放入堆栈段中.这导致打印错误.解决方案:将堆栈段移至文件底部,或切换回代码段.
  1. You initialize ss to data, not stack. Solution: Add mov ax, stack before the mov ss, ax
  2. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆