Author Topic: Input and display a string from an array in assembly using nasm  (Read 12748 times)

Offline Rixred

  • Jr. Member
  • *
  • Posts: 5
The following code runs, however, any character entered is displayed with the same symbol (an o shape underlined?). I then have to close DOSBOX otherwise the same symbol can continue to be written on 3 or so lines until freezing with just the cursor flashing. I'm still learning assembly so any help would really be appreciated.

Code: [Select]
;NASM-IDE ASM Assistant Assembler Project File
;BITS 16            ;Set code generation to 16 bit mode
;ORG 0x0100     ;Set code start address to 0100h


SEGMENT .text       ;Main code segment

MAIN:
MOV DI, array
Call GETSTRING
Call PUTLINE
MOV SI, array
Call PUTSTRING
Call PUTLINE
JMP EXIT

EXIT:
MOV AX, 4C00H
MOV AL, 00H
INT 21H

PUTCH:               
PUSH AX                                                                           
MOV AH, 02H
INT 21H
POP AX                                 
ret           

GETCH:
PUSH BX
MOV BH, AH 
MOV AH, 08H
INT 21H     
MOV AH, BH 
POP BX
ret

PUTLINE:
PUSH AX
PUSH BX
MOV AH, 0004CH
INT 21H   
POP AX
POP BX
ret

GETSTRING:
Call GETCH
Cmp DL, 0DH
JE END
Call PUTCH
STOSB
JMP GETSTRING
END:
MOV AL, 00H
STOSB
ret

PUTSTRING:
CLD
LODSB
CMP AL, 00H
JZ END1
MOV DL, AL
Call PUTCH
JMP PUTSTRING

END1:
ret

SEGMENT .data       ;Initialised data segment

mesg db 'assembly', 0DH, 0AH, '$'

CR  equ  0DH
LF  equ  0AH

SEGMENT .bss        ;Uninitialised data segment

array resb 256           ; reserves 256 bytes of space
« Last Edit: June 02, 2014, 02:06:30 AM by Rixred »

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Input and display a string from an array in assembly using nasm
« Reply #1 on: June 02, 2014, 03:48:33 AM »
Hi Rixred,

Although it's your first post here, this code looks slightly familiar. Stack Overflow? You've come to the right place. We won't downvote your question, at least. :)

I'm not familiar with NASM-IDE. I once knew of a program with a similar name - without the hyphen - but it's really, really old. If this assembles to a .com file (easiest), you want to uncomment the "org" line. It informs Nasm where Dos(Box) will load your program (doesn't cause it to be loaded there). Without it, Nasm isn't going to find either "mesg" or "array". That sounds like your problem - one of 'em at least. If it's assembled - and linked - into an .exe you need some different code. I'll ASSume that's not what you want until you tell me different. If you commented out that line because Nasm complained, I'm on the wrong track.

Your GETSTRING calls GETCH, which uses int 21h/8, which is the "no echo" character input function. It puts the character in al. GETSTRING looks for the character in dl, so you're not going to find the CR (0Dh) there. You do want it in dl for PUTCH, so put it there someplace. I'd do "mov dl, al" inside of PUTCH, rather than expecting it to be there, but it should work either way.

Then you call PUTLINE. What's that supposed to do? It looks like the "exit to dos" function, which you don't want quite yet. I'd just comment out the call to that, for now.

The rest of it looks pretty good. Start by uncommenting the "org" line and see how it goes from there. I can't try it for ya - unable to install DosBox so you're a step ahead of me there. I may wrestle with it one more time, but meanwhile I'm going from memory, which is getting pretty full of cobwebs. Get back to us if you have further trouble (or if I've missed it entirely)... tell us about NASM-IDE... Happy assemblin'!

Best,
Frank


Offline Rixred

  • Jr. Member
  • *
  • Posts: 5
Re: Input and display a string from an array in assembly using nasm
« Reply #2 on: June 02, 2014, 04:27:36 AM »
Hi Frank

Thanks for the reply and explanation. I did what you said but that unfortunately that didn't seem to have an effect - it still continues to display lines of the same symbol!

I commented out the ORG line, so the first part of it is code. I also put "mov dl, al" inside PUTCH and removed the calls for PUTLINE. I'm not sure which one you were talking about as there are two in the MAIN function, unless that's what you meant?

The whole program doesn't need to link to anything, so all it needs is the code inside it.

I'm stumped as to why it's doing this. I've attached the updated version of the code, hopefully it'll show where I'm going wrong.

Code: [Select]
               ;NASM-IDE ASM Assistant Assembler Project File
BITS 16             ;Set code generation to 16 bit mode
ORG 0x0100         ;Set code start address to 0100h


SEGMENT .text       ;Main code segment

MAIN:
MOV DI, array
Call GETSTRING
MOV SI, array
Call PUTSTRING
JMP EXIT

EXIT:
MOV AX, 4C00H
INT 21H


PUTCH:               
PUSH AX                                                                           
MOV AH, 02H
MOV DL, AL
INT 21H
POP AX                                 
ret           

GETCH:
PUSH BX
MOV BH, AH 
MOV AH, 08H
INT 21H     
MOV AH, BH 
POP BX
ret

PUTLINE:
PUSH AX
PUSH BX
MOV AH, 0004CH
INT 21H   
POP AX
POP BX
ret

GETSTRING:
Call GETCH
CMP DL, 0DH
JE END
Call PUTCH
STOSB
JMP GETSTRING

END:
MOV AL, 00H
STOSB
ret

PUTSTRING:
CLD
LODSB
CMP AL, 00H
JZ END1
MOV DL, AL
Call PUTCH
JMP PUTSTRING

END1:
ret

SEGMENT .data       ;Initialised data segment

mesg db 'assembly', 0DH, 0AH, '$'

CR  equ  0DH
LF  equ  0AH

SEGMENT .bss        ;Uninitialised data segment

array resb 256           ; reserves 256 bytes of space

I did use some of the code from Stack Overflow, by the way. I had difficulty writing the GETSTRING and PUTSTRING routines though I managed to write the PUTCH, GETCH and PUTLINE routines pretty much myself.

EDIT: I've just noticed I wrote "mov dl, dl" instead of "mov dl, al"! I feel stupid but it now works! Thank you very much, Frank. :)

EDIT 2: There is one slight issue, though. I can input and display a string of any characters but what is the string "assembly" doing? How can I display it?
« Last Edit: June 02, 2014, 05:07:15 AM by Rixred »

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Input and display a string from an array in assembly using nasm
« Reply #3 on: June 02, 2014, 05:23:41 AM »
Yeah, I just saw your latest question on SO. Thought I remembered it from before that. Earlier version, maybe. No matter, between us we'll get it working!

Code: [Select]
               ;NASM-IDE ASM Assistant Assembler Project File
BITS 16             ;Set code generation to 16 bit mode
ORG 0x0100         ;Set code start address to 0100h


SEGMENT .text       ;Main code segment

MAIN:
MOV DI, array
Call GETSTRING
MOV SI, array
Call PUTSTRING
JMP EXIT ; don't really need to jump there - won't hurt

EXIT:
MOV AX, 4C00H
INT 21H


PUTCH:               
PUSH AX                                                                           
MOV AH, 02H
MOV DL, DL ; ??? is this what you meant to do?
INT 21H
POP AX                                 
ret           

GETCH:
PUSH BX
MOV BH, AH 
MOV AH, 08H
INT 21H     
MOV AH, BH 
POP BX
ret

PUTLINE:
; what's this intended to do?
; doesn't matter 'cause we're not calling it anymore
; should just exit
PUSH AX
PUSH BX
MOV AH, 0004CH
INT 21H   
POP AX
POP BX
ret

GETSTRING:
Call GETCH

; character's in al
; you're going to want it in both places anyway
mov dl, al

CMP DL, 0DH
JE END
Call PUTCH
STOSB
JMP GETSTRING

END:
MOV AL, 00H
STOSB
ret

PUTSTRING:
CLD
LODSB
CMP AL, 00H
JZ END1
MOV DL, AL
Call PUTCH
JMP PUTSTRING

END1:
ret

SEGMENT .data       ;Initialised data segment

mesg db 'assembly', 0DH, 0AH, '$'

CR  equ  0DH
LF  equ  0AH

SEGMENT .bss        ;Uninitialised data segment

array resb 256           ; reserves 256 bytes of space

I think that might work. It isn't too great, you've reinvented "gets()" - allowed the user to enter more than will fit in your buffer. Probably not a real target for "attackerz", but we can discuss how to fix it. Get it working first.

Best,
Frank


Offline Rixred

  • Jr. Member
  • *
  • Posts: 5
Re: Input and display a string from an array in assembly using nasm
« Reply #4 on: June 02, 2014, 05:47:50 AM »
Alright, I've just removed the redundant code and made the couple of changes you've kindly made for me. I can input a string and now have it echoed, however, it's all on the same line. It's not a big issue but what should I look to do to make it appear on separate lines? I'm assuming it's something to do with the CR and LF?

Also, I still don't know what the message "assembly" is supposed to do? Do I even need it?

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Input and display a string from an array in assembly using nasm
« Reply #5 on: June 02, 2014, 06:06:16 AM »
No, you don't seem to use that string. Might be a useful "debugging tool" to make sure Nasm is finding your data, It can go.

You could call PUTCH twice with CR and LF, or you could call a separate function...
Code: [Select]
newline:
    mov ah, 2
    mov dl, CR ; you've got these defined
    int 21h
    mov dl, LF
    int 21h
    ret

Something like that (untested, from memory).

Best,
Frank


Offline Rixred

  • Jr. Member
  • *
  • Posts: 5
Re: Input and display a string from an array in assembly using nasm
« Reply #6 on: June 02, 2014, 06:39:03 AM »
Frank, you've got a great memory because that worked. The input and echo are somewhat concatenated but that doesn't matter.

I've already taken much of your time but I just have a final couple of questions. Is the input string, that is entered, put inside the 256 byte array? Also how can I null-terminate it?

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Input and display a string from an array in assembly using nasm
« Reply #7 on: June 02, 2014, 07:31:44 AM »
Yes, the string is put into the array, and you do null-terminate it:
Code: [Select]
; ...
END:
MOV AL, 00H
STOSB
ret
Are you just guessing what this code does? Pretty good guessing, but you'll want some documentation. The Intel (or AMD) manual is better, but here's a link to the old instruction set reference from the old Nasm manual. It was removed from the manual because no one wanted to maintain it. It's imperfect, but at least it's in Nasm syntax. You may find it easier to use - I do. Check out lodsb and stosb at least. The rest of 'em (that you use) are fairly obvious.

http://home.myfairpoint.net/fbkotler/nasmdocr.html

If you're going to mess with DOS, you'll want Ralf Brown's interrupt list. Here's an online version:

http://www.ctyme.com/rbrown.htm

There's more, if you download the whole thing - just search for "RBIL". The interrupt list will be your main concern,  but there's a "ports.lst" and a "memory.lst" and other goodies. Get it if you're serious about DOS (may be better uses for your time) but it's useful for other things, too.

Best,
Frank


Offline Rixred

  • Jr. Member
  • *
  • Posts: 5
Re: Input and display a string from an array in assembly using nasm
« Reply #8 on: June 02, 2014, 11:37:23 AM »
No, it wasn't a guess. I just wanted confirmation as it was actually a requirement for an assignment!

As you can tell, I'm not a great programmer and I only started learning assembly in the last couple of months but I do want to improve my programming skills in time. I don't think I'll be as good as yourself, Frank, but there's no harm in trying! Thank you for the links and extra information, I will certainly check them out and and once again, thanks a lot. You really helped me out today, or yesterday, depending on where you are in the states. :)
« Last Edit: June 02, 2014, 11:56:40 AM by Rixred »