title: DOS INT 21H Function 0AH in nasm style
body: <p>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. </p>
  
  <p>The program is equivalent to the C programming </p>
  
  <pre><code>char name[20];
  scanf("Name?%s", &amp;name);
  /*print the input name in the middle of the screen 25 * 80*/
  ....
  </code></pre>
  
  <p>My rewrite program is:</p>
  
  <pre><code>;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
  </code></pre>
  
  <p>I compile it under linux with </p>
  
  <pre><code>$ nasm -fobj A08CTRNM.asm -o a.obj
  </code></pre>
  
  <p>And link it with the link "tlink.exe" in turbo c 2.0 under dosemu</p>
  
  <pre><code>c:\tlink a.asm
  </code></pre>
  
  <p>But the linker complains something</p>
  
  <pre><code>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
  </code></pre>
  
  <p>As I run the executable file "a.exe", something is wrong</p>
  
  <pre><code>c:\a -&gt;
                        Name?
  Invalid Opcode at 00B1 02A9 0202 001B 0000 0000 0000 0000 0000 0000 0000 0000 00
  </code></pre>
  
  <p>Can You tell me how to fix the program?</p>