flat assembler
Message board for the users of flat assembler.
Index
> DOS > [SOLVED]Printing array contents? |
Author |
|
revolution 11 Feb 2012, 02:02
Do a search for what function AH=9 actually does. You are printing ASCII control characters (bell is 0x07) and it only terminates when it sees a dollar ($) symbol.
I assume you want to print the decimal value? If so then you have to convert the raw numbers into an ASCII decimal number string (with proper termination) and then print the string. |
|||
11 Feb 2012, 02:02 |
|
FASMNOOB 11 Feb 2012, 07:34
Quote: I assume you want to print the decimal value? Yup, so far I have this, not suggesting you run it. I got the functions below from this page but I'm not entirely sure how this code works. He uses the stack to store the integer and converts it to string, the returned string is in the buffer called buff1...or at least thats how I see it. I pretty much get the same error as before but with a weirder function. Code: format MZ entry cseg:Main segment cseg Main: mov ax, dseg ;These statements are provided by mov ds, ax ; shell.asm to initialize the mov es, ax ; segment register. ; AL := B2Ary2[j,k] mov bx, J ;index := (j*4+k) add bx, bx ;j*2 add bx, bx ;j*4 add bx, K ;j*4+k mov ah, 0 mov al, [B2Ary2+bx] push buff1 push ax call hex2dec ; push buff1 ; call prints Quit: mov ah, 4ch ;Magic number for DOS int 21h ; to tell this program to quit. segment dseg ; Indices we will use for the arrays. buff1 db 6 dup (0) J dw 1 K dw 2 L dw 3 ; Some two-dimensional arrays. ; Note how this code uses the "dup" operator to suggest the size ; of each dimension. B2Ary db (3*4) dup ? ;3 dup (4 dup (?)) ; 2D arrays with initialization. ; Note the use of data layout to suggest the sizes of each array. B2Ary2 db 0, 1, 2, 3 db 4, 5, 6, 7 db 8, 9, 10, 11 segment print_seg print: mov ah,9 int 21h retf dec2hex: ;push szStr; returns 4 byte value in ax push bp mov bp,sp push bx push cx push dx push si push di mov si,word [bp+4] push si call strlen mov cx,ax xor dx,dx xor ax,ax dec2hex_try: cmp cl,1 jbe dec2hex_lasta mov dl,byte [si] sub dl,30h add ax,dx mov bx,ax shl ax,1 shl ax,1 shl ax,1 add ax,bx add ax,bx inc si loop dec2hex_try dec2hex_lasta: mov dl,byte [si] sub dx,30h add ax,dx add sp,2 pop di pop si pop dx pop cx pop bx mov sp,bp pop bp ret hex2dec: ;push szOutBuff; push short; push bp ;Converts short into string and stores it mov bp,sp ;in szOutBuff push bx push cx push dx push si push di mov ax,word [bp+4] xor bx,bx xor cx,cx xor dx,dx hex2dec_a10k: cmp ax,10000 jb hex2dec_a1k sub ax,10000 inc bh jmp hex2dec_a10k hex2dec_a1k: cmp ax,1000 jb hex2dec_hundreds sub ax,1000 inc bl jmp hex2dec_a1k hex2dec_hundreds: cmp ax,100 jb hex2dec_tens sub ax,100 inc dh jmp hex2dec_hundreds hex2dec_tens: cmp ax,10 jb hex2dec_units sub ax,10 inc dl jmp hex2dec_tens hex2dec_units: mov ah,30h add bh,ah add bl,ah add dh,ah add dl,ah add al,ah cmp bh,ah jnz hex2dec_uend mov bh,20h hex2dec_u1: cmp bl,ah jnz hex2dec_uend cmp bh,20h jnz hex2dec_uend mov bl,20h cmp dh,ah jnz hex2dec_uend cmp bl,20h jnz hex2dec_uend mov dh,20h cmp dl,ah jnz hex2dec_uend cmp dh,20h jnz hex2dec_uend mov dl,020H hex2dec_uend: mov si,word [bp+6] mov byte [si],bh inc si mov byte [si],bl inc si mov byte [si],dh inc si mov byte [si],dl inc si mov byte [si],al inc si mov byte [si],0 pop di pop si pop dx pop cx pop bx mov sp,bp pop bp ret strlen: ;push szStr push bp ;Returns length of string in ax mov bp,sp push bx push cx push dx push si push di mov si,word [bp+4] xor dx,dx xor ax,ax strlen_loop: mov dl,byte [si] cmp dl,0 je strlen_break inc ax inc si jmp strlen_loop strlen_break: pop di pop si pop dx pop cx pop bx mov sp,bp pop bp ret ;Jakash3's basic i/o library. Unless otherwise commented, ;each function returns the current cursor position. ;return values placed in ax after function call. ;arguments for functions pushed to stack. printc: ;printc(byte c) push bp mov bp,sp push bx push cx push dx push si push di mov ah,0fh int 10h mov ah,0ah mov al,byte [bp+4] cmp al,0dh je printc_cr cmp al,0ah je printc_lf jmp printc_continue printc_cr: mov ah,03 int 10h mov dl,0 mov ah,02 int 10h jmp printc_done printc_lf: mov ah,03 int 10h inc dh mov ah,02 int 10h jmp printc_done printc_continue: mov cx,1 int 10h call inccur printc_done: mov ah,03 int 10h mov ah,dh mov al,dl pop di pop si pop dx pop cx pop bx mov sp,bp pop bp ret prints: ;prints(word str_ptr) push bp mov bp,sp push bx push cx push dx push si push di mov bx,word [bp+4] sub sp,1 prints_loop: mov dl,byte [bx] cmp dl,0 jz prints_done mov byte [bp-11],dl call printc inc bx jmp prints_loop prints_done: mov ah,03 int 10h mov ah,dh mov al,dl pop di pop si pop dx pop cx pop bx mov sp,bp pop bp ret inputc: ;byte inputc() push bp ;returns byte value of single character input mov bp,sp push bx push cx push dx push si push di mov ah,00 int 16h sub sp,2 mov byte [bp-11],al mov byte [bp-12],al call printc mov ah,0 mov al,byte [bp-11] pop di pop si pop dx pop cx pop bx mov sp,bp pop bp ret inputs: ;byte inputs(byte len,word buff_ptr) push bp ;returns number of bytes read from input mov bp,sp push bx push cx push dx push si push di sub sp,1 mov bx,word [bp+4] mov ch,byte [bp+6] xor cl,cl input_L1: mov ah,0 int 16h cmp al,08 je input_bksp cmp al,0dh je input_br1 cmp cl,ch jge input_L1 mov byte [bx],al inc bx mov byte [bp-11],al call printc inc cl jmp input_L1 input_bksp: cmp cl,0 je input_L1 mov byte [bx],0 dec bx mov byte [bx],0 mov byte [bp-11],0 call printc call deccur call deccur call printc call deccur dec cl jmp input_L1 input_br1: mov byte [bx],0 mov ah,0 mov al,cl pop di pop si pop dx pop cx pop bx mov sp,bp pop bp ret deccur: ;decrease cursor position push bp mov bp,sp push bx push cx push dx push si push di sub sp,1 mov ah,0fh int 10h mov byte [bp-11],ah mov ah,03 int 10h cmp dl,0 jne deccur_continue mov dl,byte [bp-11] dec dh jmp deccur_done deccur_continue: dec dl deccur_done: mov ah,02 int 10h add sp,1 mov ah,03 int 10h mov ah,dh mov dl,dl pop di pop si pop dx pop cx pop bx mov sp,bp pop bp ret inccur: ;increase cursor position push bp mov bp,sp push bx push cx push dx push si push di sub sp,1 mov ah,0fh int 10h mov byte [bp-11],ah mov ah,03 int 10h cmp dl,byte [bp-11] jne inccur_continue mov dl,0 inc dh jmp inccur_done inccur_continue: inc dl inccur_done: mov ah,02 int 10h add sp,1 mov ah,03 int 10h mov ah,dh mov al,dl pop di pop si pop dx pop cx pop bx mov sp,bp pop bp ret |
|||
11 Feb 2012, 07:34 |
|
FASMNOOB 11 Feb 2012, 10:41
I tried this another way printing out text, I assume its ascii in the array this time and that also crashed?
Code: format MZ entry cseg:Main stack 100h segment cseg Main: mov ax, dseg ;These statements are provided by mov ds, ax ; shell.asm to initialize the mov es, ax ; segment register. ; AL := B2Ary2[j,k] mov bx, J ;index := (j*4+k) add bx, bx ;j*2 add bx, bx ;j*4 add bx, K ;j*4+k mov al, [B2Ary2+bx] call print_seg:print Quit: mov ah, 4ch ;Magic number for DOS int 21h ; to tell this program to quit. segment dseg J dw 1 K dw 2 L dw 3 B2Ary db (3*4) dup ? ;3 dup (4 dup (?)) B2Ary2 db '0', '1', '2', '3' db '4', '5', '6', '7' db '8', '9', '10', '11' segment print_seg print: mov ah,9 int 21h retf |
|||
11 Feb 2012, 10:41 |
|
AsmGuru62 11 Feb 2012, 12:30
I think AH=9 function takes the address of whatever to be printed in register DX. I do not see where you set the DX.
Also, you need to understand the difference between a string, which you can print and a binary number, which you can use to do math. Code: db '11' db 11 These definitions are not the same. The first one is a string, it has a room of two bytes and both are set to a value of digit '1'. The second definition is a binary value of 11 fit into one byte. When you perform the calculations - you can use only binary representation. Once you have the result - you must convert it to a string for printing. Code: Value1 dw 6373 Value2 dw 9487 Result dw 0 StrResult rb 16 ... mov ax, [Value1] add ax, [Value2] mov [Result], ax Now, you need to convert the WORD in Result to a string (StrResult). After converting you need to append the character '$' to the end of the converted value and then use AH=9 Function to print it, but you need to put an address of StrResult into DX before the INT 21H. Search this forum - there was a lot of examples of such conversion. When you get the value from a user (of from a text file) - opposite operation is performed. User enters a string (for example "52628") and your code does a string to binary conversion - resulting in a 16-bit value, which can be used to do some calculations. P.S. I have a small DOS program, which does binary operation on 16-bit values. It has all these conversions inside. Send me an empty email to: asmguru62@hotmail.com and I will reply with the code. |
|||
11 Feb 2012, 12:30 |
|
Picnic 11 Feb 2012, 12:47
FASMNOOB wrote:
Hello, Fix your two dimensional array code. Notice the use of brackets. Code: ; AL := B2Ary2[j,k] mov bx, [J] ;index := (j*4+k) add bx, bx ;j*2 add bx, bx ;j*4 add bx,[K] ;j*4+k Move the data segment dseg at the end of code. Remove these lines Code: segment print_seg print: mov ah,9 int 21h retf Unmark commented lines and run code, it does work. FASMNOOB wrote: I tried this another way printing out text, I assume its ascii in the array this time and that also crashed? Checkout how to use INT 21h / AH=9. So, to display the array letters as ASCII string, replace Code: ;mov al, [B2Ary2+bx] mov dx, B2Ary2 and also add a '$' Code: B2Ary2 db '0', '1', '2', '3' db '4', '5', '6', '7' db '8', '9', '10', '11' db '$' Ouputs: 01234567891011 It's probably best to experiment with small routines separately. |
|||
11 Feb 2012, 12:47 |
|
FASMNOOB 12 Feb 2012, 06:04
Thanks,
I fixed them both: Code: format MZ entry cseg:Main segment cseg Main: mov ax, dseg ;These statements are provided by mov ds, ax ; shell.asm to initialize the mov es, ax ; segment register. ; AL := B2Ary2[j,k] mov bx, [J] ;index := (j*4+k) add bx, bx ;j*2 add bx, bx ;j*4 add bx, [K] ;j*4+k mov ah, 0 mov al, [B2Ary2+bx] push buff1 push ax call hex2dec push buff1 call prints Quit: mov ah, 4ch ;Magic number for DOS int 21h ; to tell this program to quit. dec2hex: ;push szStr; returns 4 byte value in ax push bp mov bp,sp push bx push cx push dx push si push di mov si,word [bp+4] push si call strlen mov cx,ax xor dx,dx xor ax,ax dec2hex_try: cmp cl,1 jbe dec2hex_lasta mov dl,byte [si] sub dl,30h add ax,dx mov bx,ax shl ax,1 shl ax,1 shl ax,1 add ax,bx add ax,bx inc si loop dec2hex_try dec2hex_lasta: mov dl,byte [si] sub dx,30h add ax,dx add sp,2 pop di pop si pop dx pop cx pop bx mov sp,bp pop bp ret hex2dec: ;push szOutBuff; push short; push bp ;Converts short into string and stores it mov bp,sp ;in szOutBuff push bx push cx push dx push si push di mov ax,word [bp+4] xor bx,bx xor cx,cx xor dx,dx hex2dec_a10k: cmp ax,10000 jb hex2dec_a1k sub ax,10000 inc bh jmp hex2dec_a10k hex2dec_a1k: cmp ax,1000 jb hex2dec_hundreds sub ax,1000 inc bl jmp hex2dec_a1k hex2dec_hundreds: cmp ax,100 jb hex2dec_tens sub ax,100 inc dh jmp hex2dec_hundreds hex2dec_tens: cmp ax,10 jb hex2dec_units sub ax,10 inc dl jmp hex2dec_tens hex2dec_units: mov ah,30h add bh,ah add bl,ah add dh,ah add dl,ah add al,ah cmp bh,ah jnz hex2dec_uend mov bh,20h hex2dec_u1: cmp bl,ah jnz hex2dec_uend cmp bh,20h jnz hex2dec_uend mov bl,20h cmp dh,ah jnz hex2dec_uend cmp bl,20h jnz hex2dec_uend mov dh,20h cmp dl,ah jnz hex2dec_uend cmp dh,20h jnz hex2dec_uend mov dl,020H hex2dec_uend: mov si,word [bp+6] mov byte [si],bh inc si mov byte [si],bl inc si mov byte [si],dh inc si mov byte [si],dl inc si mov byte [si],al inc si mov byte [si],0 pop di pop si pop dx pop cx pop bx mov sp,bp pop bp ret strlen: ;push szStr push bp ;Returns length of string in ax mov bp,sp push bx push cx push dx push si push di mov si,word [bp+4] xor dx,dx xor ax,ax strlen_loop: mov dl,byte [si] cmp dl,0 je strlen_break inc ax inc si jmp strlen_loop strlen_break: pop di pop si pop dx pop cx pop bx mov sp,bp pop bp ret ;Jakash3's basic i/o library. Unless otherwise commented, ;each function returns the current cursor position. ;return values placed in ax after function call. ;arguments for functions pushed to stack. printc: ;printc(byte c) push bp mov bp,sp push bx push cx push dx push si push di mov ah,0fh int 10h mov ah,0ah mov al,byte [bp+4] cmp al,0dh je printc_cr cmp al,0ah je printc_lf jmp printc_continue printc_cr: mov ah,03 int 10h mov dl,0 mov ah,02 int 10h jmp printc_done printc_lf: mov ah,03 int 10h inc dh mov ah,02 int 10h jmp printc_done printc_continue: mov cx,1 int 10h call inccur printc_done: mov ah,03 int 10h mov ah,dh mov al,dl pop di pop si pop dx pop cx pop bx mov sp,bp pop bp ret prints: ;prints(word str_ptr) push bp mov bp,sp push bx push cx push dx push si push di mov bx,word [bp+4] sub sp,1 prints_loop: mov dl,byte [bx] cmp dl,0 jz prints_done mov byte [bp-11],dl call printc inc bx jmp prints_loop prints_done: mov ah,03 int 10h mov ah,dh mov al,dl pop di pop si pop dx pop cx pop bx mov sp,bp pop bp ret inputc: ;byte inputc() push bp ;returns byte value of single character input mov bp,sp push bx push cx push dx push si push di mov ah,00 int 16h sub sp,2 mov byte [bp-11],al mov byte [bp-12],al call printc mov ah,0 mov al,byte [bp-11] pop di pop si pop dx pop cx pop bx mov sp,bp pop bp ret inputs: ;byte inputs(byte len,word buff_ptr) push bp ;returns number of bytes read from input mov bp,sp push bx push cx push dx push si push di sub sp,1 mov bx,word [bp+4] mov ch,byte [bp+6] xor cl,cl input_L1: mov ah,0 int 16h cmp al,08 je input_bksp cmp al,0dh je input_br1 cmp cl,ch jge input_L1 mov byte [bx],al inc bx mov byte [bp-11],al call printc inc cl jmp input_L1 input_bksp: cmp cl,0 je input_L1 mov byte [bx],0 dec bx mov byte [bx],0 mov byte [bp-11],0 call printc call deccur call deccur call printc call deccur dec cl jmp input_L1 input_br1: mov byte [bx],0 mov ah,0 mov al,cl pop di pop si pop dx pop cx pop bx mov sp,bp pop bp ret deccur: ;decrease cursor position push bp mov bp,sp push bx push cx push dx push si push di sub sp,1 mov ah,0fh int 10h mov byte [bp-11],ah mov ah,03 int 10h cmp dl,0 jne deccur_continue mov dl,byte [bp-11] dec dh jmp deccur_done deccur_continue: dec dl deccur_done: mov ah,02 int 10h add sp,1 mov ah,03 int 10h mov ah,dh mov dl,dl pop di pop si pop dx pop cx pop bx mov sp,bp pop bp ret inccur: ;increase cursor position push bp mov bp,sp push bx push cx push dx push si push di sub sp,1 mov ah,0fh int 10h mov byte [bp-11],ah mov ah,03 int 10h cmp dl,byte [bp-11] jne inccur_continue mov dl,0 inc dh jmp inccur_done inccur_continue: inc dl inccur_done: mov ah,02 int 10h add sp,1 mov ah,03 int 10h mov ah,dh mov al,dl pop di pop si pop dx pop cx pop bx mov sp,bp pop bp ret segment dseg ; Indices we will use for the arrays. buff1 db 6 dup (0) J dw 1 K dw 2 L dw 3 B2Ary db (3*4) dup ? ;3 dup (4 dup (?)) B2Ary2 db 0, 1, 2, 3 db 4, 5, 6, 7 db 8, 9, 10, 11 Code: format MZ entry cseg:Main stack 100h segment cseg Main: mov ax, dseg ;These statements are provided by mov ds, ax ; shell.asm to initialize the mov es, ax ; segment register. ; AL := B2Ary2[j,k] mov bx, J ;index := (j*4+k) add bx, bx ;j*2 add bx, bx ;j*4 add bx, K ;j*4+k mov ax, [B2Ary2+bx] mov dx,B2Ary2 call print_seg:print Quit: mov ah, 4ch ;Magic number for DOS int 21h ; to tell this program to quit. segment dseg J dw 1 K dw 2 L dw 3 B2Ary db (3*4) dup ? ;3 dup (4 dup (?)) B2Ary2 db '0', '1', '2', '3' db '4', '5', '6', '7' db '8', '9', '10', '11' db '$' segment print_seg print: mov ah,9 int 21h retf |
|||
12 Feb 2012, 06:04 |
|
FASMNOOB 12 Feb 2012, 06:08
Quote: The second definition is a binary value of 11 fit into one byte. Is this also true for 32-bit windows programming. Do I need to convert back and forth between strings and numbers? Say I wanted to create a window which can take input and use it to calculate numbers and display them like a calculator for example? |
|||
12 Feb 2012, 06:08 |
|
revolution 12 Feb 2012, 06:38
You can do direct computations on ASCII decimal with the x86 instructions AAD, AAS etc. but I would not recommend it. Converting to binary upon input, and converting to ASCII on output, is by far the easiest way to avoid errors and confusion.
|
|||
12 Feb 2012, 06:38 |
|
FASMNOOB 12 Feb 2012, 06:49
Quote: but I would not recommend it. Are there limits to the size of the variable. I did try looking for it but none of the sites I went to gave caveats. |
|||
12 Feb 2012, 06:49 |
|
revolution 12 Feb 2012, 09:03
FASMNOOB wrote: Are there limits to the size of the variable. I did try looking for it but none of the sites I went to gave caveats. |
|||
12 Feb 2012, 09:03 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.