Author Topic: how to read from a buffer  (Read 25154 times)

Offline flyhigh427

  • Jr. Member
  • *
  • Posts: 60
how to read from a buffer
« on: July 24, 2011, 10:35:26 PM »
do you read from a buffer the same way as reading from a file?

thanks


Code: [Select]
org 100h                                ;

Start:





;read mbr
        mov     dx,00h                  ;DX Data register  ; read MBR of target drive
                                        ;drive a=ooh,b=01h,80h=first hard drive.81h=second

        mov     cx,1h                   ;CX count register for string operations ; it's always the first sector

        mov     bx, buffer              ;BX index register for MOVE ; point to our buffer

        mov     ax, 0201h               ;AX Accumulator/multiply/divide ; read one sector

        int     13h                     ;13h is Drive Table
;file stuff
       
       
        mov     ah, 3Ch         ;create  the file
        mov     cx, 0       
        lea     dx, [Filename]  ;Presume DS points at filename
        int     21h             ; segment.
       
;put read from buffer here





;put write to file here




        mov     ah, 3eh         ;Close file
        int     21h           
        jmp     stop

stop:

        mov     ax, 0x4C00           ; Terminate program
        int     21h







buffer times 512 db 0                           

Filename         db 'test.txt',0



Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: how to read from a buffer
« Reply #1 on: July 25, 2011, 07:07:18 AM »
Code: [Select]
org 100h                                ;

Start:





;read mbr
        mov     dx,00h                  ;DX Data register  ; read MBR of target drive
                                        ;drive a=ooh,b=01h,80h=first hard drive.81h=second

        mov     cx,1h                   ;CX count register for string operations ; it's always the first sector

        mov     bx, buffer              ;BX index register for MOVE ; point to our buffer

        mov     ax, 0201h               ;AX Accumulator/multiply/divide ; read one sector

        int     13h                     ;13h is Drive Table
;file stuff
       
       
        mov     ah, 3Ch         ;create  the file
        mov     cx, 0       
        lea     dx, [Filename]  ;Presume DS points at filename
        int     21h             ; segment.
        jc stop                  ; don't continue if create failed!
       mov [handle], ax
       
;put read from buffer here
; "read from"? you mean display it?
; this won't be too useful... hex display better?
       mov dx, buffer
       mov cx, 512
       mov bx, 1 ; stdout
       mov ah, 40h
       int 21h


;put write to file here

        mov dx , buffer
        mov cx, 512
        mov bx, [handle]
        mov ah, 40h
        int 21h


        mov     ah, 3eh         ;Close file
        int     21h           
        jmp     stop

stop:

        mov     ax, 0x4C00           ; Terminate program
        int     21h

buffer times 512 db 0                           

Filename         db 'test.txt',0

Untested!

Best,
Frank



Offline flyhigh427

  • Jr. Member
  • *
  • Posts: 60
Re: how to read from a buffer
« Reply #2 on: July 25, 2011, 09:53:35 AM »
thanks frank i have alot to learn

Offline MJaoune

  • Jr. Member
  • *
  • Posts: 94
Re: how to read from a buffer
« Reply #3 on: July 25, 2011, 12:12:15 PM »

Untested!

Best,
Frank

As you always say Frank: "If you see some smoke, pull the plug" :P hahaha


If anyone wants, he can link C or C++ with Nasm, you can use "fstream" in C++ or std library in C, but I always recommend Assembly, especially NASM.

Best,
Mahmoud

Offline flyhigh427

  • Jr. Member
  • *
  • Posts: 60
Re: how to read from a buffer
« Reply #4 on: July 25, 2011, 11:43:11 PM »
hey yall
ive been googling buffers for awhile now ,does any know where i can get alot more info on buffers ?
thanks

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: how to read from a buffer
« Reply #5 on: July 26, 2011, 12:33:33 AM »
A "buffer" is just an area of memory. What sort of info are you looking for, Flyhigh427?

Best,
Frank


Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: how to read from a buffer
« Reply #6 on: July 26, 2011, 01:27:26 AM »
In view of your post to the AsmCommunity board (you didn't think you were going to get away from me?), here are a couple of files that might interest you. They read the MBR(s) by a different method - reading the ports on the IDE controller. This won't work in a "dos box" under Windows, as I recall. Should work in "real dos" (dunno about an emulator like "dosbox"). If your drive(s) aren't IDE, it won't work, of course. You can replace the "read MBR to buffer" with the int 13h routine you've got, if you need to.

The "print hex" routine is an "obsessively short" one shown to me by Ben Lunt (he thanks others for help). If you need an "easy to understand" print hex routine, we can discuss that...

I'm too lazy to (re-)test these now. As I recall, one prints the whole MBR(s), the others print just the partition table(?). The "read IDE controller from ports" was posted by Kirk Lawrence (who no longer posts - hope he's okay! - so I figure it's okay to "out" him). He is/was a big a86 fan, thus the "proprietory cruft" comment. They are in fact in Nasm syntax. Give you something to play with/study, if nothing else! :)

Best,
Frank


Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: how to read from a buffer
« Reply #7 on: July 26, 2011, 01:32:42 AM »
Oops, meant to attach more files...

Best,
Frank


Offline flyhigh427

  • Jr. Member
  • *
  • Posts: 60
Re: how to read from a buffer
« Reply #8 on: July 26, 2011, 12:42:22 PM »
im sorry i didnt answer yeasterday bed time .
ive been useing the art of ASSEMBLY LANGUAGE book and others ,but what had me baffled was what you said about  display the buffer and using hex instead of stdout .
so the buffer deals with the memory .you would think it would be more about it in the books.
thanks 
i try not to ask many questions but i get  stuck.

Offline flyhigh427

  • Jr. Member
  • *
  • Posts: 60
Re: how to read from a buffer
« Reply #9 on: July 26, 2011, 03:21:35 PM »
hey frank
if you have a minute.

"easy to understand" print hex routine
where do i start
thanks

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: how to read from a buffer
« Reply #10 on: July 27, 2011, 09:03:09 AM »
Start by thinking through what we need to do. I often advocate writing the comments first (although I rarely actually do it). We're going to need to generate an ascii character to represent each group of four bits (a nibble... or nybble if you like). The groups of four bits will contain a number from 0 to 15. We're going to want to "convert" these to ascii characters '0' through 'F'. '0' to '9' is easy - just add '0' (48 decimal or 30h hex), same as a decimal conversion. 'A' through 'F' don't follow immediately after '9', we need to add an extra 7 (27h if you want 'a' through 'f'). We need to process these in the correct order. We could isolate the first (most significant) 4 bits and shift 'em down, then the next four... The "rol" instruction comes in handy here. We can rotate the top 4 bits into the lowest 4 bit positions, where they'll be easy to print. If we keep doing this, we'll get each group of four bits - in order - and get our original number back. Unfortunately, we have to isolate the four bits to "convert" and print them, and this will trash our number - we'll have to make a copy. If you're using a dos interrupt that prints dl, making a copy in dl may be convenient (but you'll probably still have to save ax). We isolate 4 bits, add '0', check to see if we have to add another 7, and print it. then we loop back and "rol" another four into position... until done.

; initialize counter
; looptop:
; rotate 4 into position
; save number
; isolate lowest 4 bits
; add '0'
; if it's over '9'
; add 7
; print it
; restore our number
; loop looptop
; return

Or as a real Linux program:

Code: [Select]
; nasm -f elf32 printhex.asm
; ld -o printhex printhex.o

global _start

section .text
_start:
    nop
    mov eax, 1234ABCDh
    call printhex
    mov al, 10 ; cosmetic linefeed
    call putc
exit:   
    mov eax, 1
    int 80h

printhex:
    mov ecx, 8  ; 8 digits to print
.top:
    rol eax, 4
    push eax
    and al, 0Fh
    add al, '0'
    cmp al, '9'
    jbe .skip
    add al, 7
.skip:
    call putc
    ; or
    ; stosb
    ; for dos
    ; mov ah, 0Eh
    ; mov bx, 7
    ; int 10h
    ; or
    ; int 29h
    pop eax
    sub ecx, 1
    jnz .top
    ; or
    ; loop .top
    ret

putc:
    push edx
    push ecx
    push ebx
    push eax
    mov ecx, esp
    mov edx, 1
    mov ebx, 1
    mov eax, 4
    int 80h
    pop eax
    pop ebx
    pop ecx
    pop edx
    ret
;-------------------

If you're only doing bytes, there are easier ways, but it's the same general principle. A lookup table is also pretty simple.

Code: [Select]
hexdigits db '0123456789ABCDEF"

and use the isolated four bits as an index into that table, instead of the add '0', etc. Yeah, that's better - saves the conditional jump...

Code: [Select]
...
; save number
and eax, 0Fh
mov al, [hexdigits + eax]
; print (or stosb)
...

Something like that...

Best,
Frank


Offline flyhigh427

  • Jr. Member
  • *
  • Posts: 60
Re: how to read from a buffer
« Reply #11 on: July 27, 2011, 12:51:16 PM »
is it allright to mix 16 and 32 bit  like this program does ?
and
thanks frank and everyone for your help

Offline flyhigh427

  • Jr. Member
  • *
  • Posts: 60
Re: how to read from a buffer
« Reply #12 on: July 28, 2011, 06:11:20 PM »
hey yall good morning
if im testing in windows and running these 16 bit from the command prompt.
will they work right?
and im still trying to  open a file and put it in a buffer then display it to another file.
it creates a file but thats all.
if yall see any mistakes please ,holler
thanks for your time

Code: [Select]
org 100h                                ;

Start:
                call        createfile               
                mov     ah, 3dh         ;Open the file
                mov     al, 0           ;Open for reading
                mov     dx, [Filename1] ;Presume DS points at filename
                int     21h             ; segment.
                jc      OpenError
                mov     [handle1], ax   ;Save file handle






LP:

                mov     ah,3fh          ;Read data from the file
                mov     bx, [handle1]   ;Get file handle value               
                mov     cx, 1           ;Read one byte
                mov     dx, buffer      ;Address of data buffer
                int     21h               
                jc      ReadError
                cmp     ax, cx          ;EOF reached?
                jne     EOF
                mov     al, buffer      ;Get character read                   
                call write              ;Print it
                jmp     LP            ;Read next byte


EOF:
                mov     bx, [handle1]
                mov     ah, 3eh         ;Close file
                int     21h
                mov     bx, [handle2]
                mov     ah, 3eh         ;Close file
                int     21h
                jmp     stop


write:
               
mov ah, 40h
                mov bx, [handle2]
                mov cx, 1
mov dx, buffer          ;char to be printed               
int 21h
               ; jc display_error        ; error? display message.
               ; cmp ax,100h             ; all bytes written?
               ; jne eof                 ; no: disk is full
ret


stop:

                mov     ax, 0x4C00      ; Terminate program
                int     21h   

createfile:

                mov     ah, 3Ch         ;create  the file
                mov     cx, 0       
                lea     dx, [Filename2] ;Presume DS points at filename
                int     21h             ; segment.
                jc      stop            ; don't continue if create failed!
                mov     [handle2], ax       
                ret
OpenError:
          jmp stop

ReadError:
          jmp stop

buffer times 512 db 0
Filename1        db 'test1.txt',0
Filename2        db 'test2.txt',0
handle1          db  0
handle2          db  0





Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: how to read from a buffer
« Reply #13 on: July 28, 2011, 08:21:26 PM »
To get to an earlier question... yeah, it's okay to use 32-bit instructions in 16-bit code (assuming we're running on 32-bit hardware!). There are some limitations (offsets can't exceed 64k), but it works...

Now... yeah there are some errors here...

Code: [Select]
org 100h                                ;

Start:
                call        createfile               
                mov     ah, 3dh         ;Open the file
                mov     al, 0           ;Open for reading
;                mov     dx, [Filename1] ;Presume DS points at filename
               mov dx, filename1
; or          lea dx, [filename1]
; either will get the address of "filename1" into dx
; "lea" = "load effective address"

               int     21h             ; segment.
                jc      OpenError
                mov     [handle1], ax   ;Save file handle

LP:
                mov     ah,3fh          ;Read data from the file
                mov     bx, [handle1]   ;Get file handle value               
                mov     cx, 1           ;Read one byte
                mov     dx, buffer      ;Address of data buffer
                int     21h               
                jc      ReadError
                cmp     ax, cx          ;EOF reached?
                jne     EOF
; might be better to check for ax=0 here

;                mov     al, buffer      ;Get character read                   
                mov al, [buffer]    ; we want "[contents]"!
                call write              ;Print it
; ... but your "write" routine doesn't print what's in al
; want to print what's in al?
     int 29h  ; quick and dirty

                jmp     LP            ;Read next byte

EOF:
                mov     bx, [handle1]
                mov     ah, 3eh         ;Close file
                int     21h
                mov     bx, [handle2]
                mov     ah, 3eh         ;Close file
                int     21h
                jmp     stop

write:
               
mov ah, 40h
                mov bx, [handle2]
                mov cx, 1
mov dx, buffer          ;char to be printed               
int 21h
               ; jc display_error        ; error? display message.
               ; cmp ax,100h             ; all bytes written?
               ; jne eof                 ; no: disk is full
ret


stop:

                mov     ax, 0x4C00      ; Terminate program
                int     21h   

createfile:

                mov     ah, 3Ch         ;create  the file
                mov     cx, 0       
                lea     dx, [Filename2] ;Presume DS points at filename
                int     21h             ; segment.
                jc      stop            ; don't continue if create failed!
                mov     [handle2], ax       
                ret
OpenError:
          jmp stop

ReadError:
          jmp stop

buffer times 512 db 0
Filename1        db 'test1.txt',0
Filename2        db 'test2.txt',0

;handle1          db  0
handle1          dw 0 ; we need a word!

;handle2          db  0
handle2          dw 0

I'm not sure it'll work with those corrections, but worth another try, I think...

Or try this one...

Best,
Frank





Offline flyhigh427

  • Jr. Member
  • *
  • Posts: 60
Re: how to read from a buffer
« Reply #14 on: July 28, 2011, 10:20:59 PM »
hey i put hello in the test1.txt file and it prints hex into test2.txt ,i think.
but i did that 3 times and each time it printed different charecters each time.
is that normol?
and if it was a backup of my mbr would that cause a problem?
thanks

Code: [Select]
org 100h
section .text


start:
;create test2.txt


    mov ah,03Ch        ; the open/create-a-file function
    mov cx,020h        ; file attribute - normal file
    mov dx,filename1   ; address of a ZERO TERMINATED! filename string
    int 021h           ; call on Good Old Dos
    mov [filehndl2],ax ; returns a file handle (probably 5)
     


;read from test1.txt
   
    mov ah,03Fh        ; the read-from-a-file function
    mov bx,[filehndl]  ; file handle
    mov cx,5           ; max bytes to read
    mov dx,textbuf     ; address of a buffer to read into
    int 021h           ; call on Good Old Dos
 

;close test1.txt


    mov ah,03Eh        ; close the file
    mov bx,[filehndl]  ; yeah, file handle in bx
    int 021h           ; call on Good Old Dos





;write to test2.txt


    mov ah,040h        ; write-to-a-file
    mov bx,[filehndl2] ; file handle for standard output
    mov cx,5           ; bytes to write - same number we read :)
    mov dx,textbuf     ; buffer to write from
    int 021h           ; call on Good Old Dos


;close test2.txt

    mov ah,03Eh        ; close the file
    mov bx,[filehndl2] ; yeah, file handle in bx
    int 021h           ; call on Good Old Dos




exit:
    mov ah,04Ch         ; terminate-program function
    int 021h            ; you guessed it!
 
;--------------------------------------------------
section .data
    msg db 'Please enter some text...',0Dh,0Ah
    filename1 db 'test2.txt',0
    filename db 'test1.txt',0
;--------------------------------------------------
section .bss
    textbuf resb 0100h
   
    text_len resw 01h
   
    filehndl resw 01h
    filehndl2 resw 01h