NASM - The Netwide Assembler
NASM Forum => Using NASM => Topic started by: flyhigh427 on July 24, 2011, 10:35:26 PM
-
do you read from a buffer the same way as reading from a file?
thanks
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
-
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
-
thanks frank i have alot to learn
-
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
-
hey yall
ive been googling buffers for awhile now ,does any know where i can get alot more info on buffers ?
thanks
-
A "buffer" is just an area of memory. What sort of info are you looking for, Flyhigh427?
Best,
Frank
-
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
-
Oops, meant to attach more files...
Best,
Frank
-
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.
-
hey frank
if you have a minute.
"easy to understand" print hex routine
where do i start
thanks
-
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:
; 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.
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...
...
; save number
and eax, 0Fh
mov al, [hexdigits + eax]
; print (or stosb)
...
Something like that...
Best,
Frank
-
is it allright to mix 16 and 32 bit like this program does ?
and
thanks frank and everyone for your help
-
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
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
-
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...
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
-
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
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
-
Lemme see... you open "filename1", which is "test2", and put the handle in "filehndl2". Have I got that right? (really should check the carry-flag to make sure the open succeeded before you try to use it!)
Then you attempt to read from "filehndl", which is... what? Still "uninitialized", isn't it? In executable formats other than .com (all that I'm aware of), the loader will initialize .bss to zero, but in a .com file it could be any garbage. This probably won't work.
Then you write to "filehndl2"... This might put "hellohello" in the file that just had "hello" in it... no, I think I'm lost at this point...
It is not normal that this should print hex anywhere. It is not normal that it should do something different each time. Trashing a "backup" of your MBR shouldn't cause a problem, unless you try to use it. Trashing your actual MBR definitely will cause a problem! Dos "file" functions won't read/write your MBR, but be very careful with int 13h!!!
Keep trying, I don't think you've got it yet...
Best,
Frank
-
its way different then vb 6 thats for sure
thanks frank
-
im haveing trouble with this line >> mov [read_len],ax ; returns number of bytes actually
i cant figure out how count up the bytes then put that number in read read_ien
org 100h
section .text
start:
;open test1.txt
mov ah, 3dh ;Open the file
mov al, 0 ;Open for reading
mov dx, filename1 ;Presume DS points at filename
int 21h ; segment.
jc BadOpen
mov [filehnd1], ax ;Save file handle
;read from test1.txt 1 byte at a time into buffer
LP:
mov ah,3fh ;Read data from the file
mov bx, [filehnd1] ;Get file handle value
mov cx, 1
mov dx, textbuf ;Address of data buffer
int 21h
jc ReadError
cmp ax, 0 ;EOF reached?
jne EOF
mov [read_len],ax ; returns number of bytes actually
jmp LP ;Read next byte
EOF:
mov bx, [filehnd1]
mov ah, 3eh ;Close file
int 21h
jc CloseError
;create test2.txt
mov ah,3Ch ; the open/create-a-file function
mov cx,2 ; file attribute - normal file
mov dx,filename2 ; address of a ZERO TERMINATED! filename string
int 021h ; call on Good Old Dos
jc BadOpen
mov [filehnd2],ax ; returns a file handle (probably 5)
;write to test2.txt
mov ah,040h ; write-to-a-file
mov bx,[filehnd2] ; file handle for standard output
mov cx,read_len ; 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,[filehnd2] ; yeah, file handle in bx
int 021h ; call on Good Old Dos
jc CloseError
jmp exit
CloseError:
mov dx,msgclose
mov ah,09
int 21h
xor ax,ax
int 016h
jmp exit
ReadError:
mov dx,msgread
mov ah,09
int 21h
xor ax,ax
int 016h
jmp exit
BadOpen:
mov dx,msgopen
mov ah,09
int 21h
xor ax,ax
int 016h
jmp exit
exit:
mov ah,04Ch ; terminate-program function
int 021h ; you guessed it!
;--------------------------------------------------
section .data
msgclose db "unable to close file...", 0x0d, 0x0a, '$'
msgread db "read error...", 0x0d, 0x0a, '$'
msgopen db "open error...", 0x0d, 0x0a, '$'
filename2 db 'test2.txt',0
filename1 db 'test1.txt',0
;--------------------------------------------------
textbuf times 100 db 0
filehnd1 db 0
filehnd2 db 0
read_len db 0
-
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
Maybe you have used the "mov" function to move the address, so you didn't use the [] brackets, double check the code (I was too lazy to read it) and see if you have "mov"ed the address of a register or a value and not the data.
If you are not using the brackets, then it would be equivalent to the C code:
int *p;
int tod;
p = &tod;
And then printing p to screen
By hex you must mean the address.
Best,
Mahmoud
-
You don't count 'em, dos does.
http://www.ctyme.com/intr/rb-2783.htm
There's an error in your code, however!
cmp ax, 0 ;EOF reached?
jne EOF
If "number of bytes read" is zero, you're at EOF.
Edit: Further, you need a word, not a byte, for each of your file handles!
Edit2: And for "len_read"!
Best,
Frank
-
its way different then vb 6 thats for sure
I dunno. We'd "say it" differently, but we should be doing the same functions. If we made the same errors - "dimensioning" a variable to the wrong size - it would give the same wrong results... but vb would probably generate an error.
HLLs need to know a lot of information about "types" since they need to generate the instructions. In asm, we're generating the instructions, so we need to keep track of "types", but the assembler doesn't need to know. There's more to "type" than "size". For example, a dword could represent an integer or a single-precision "float". Inappropriate instructions for a "type" will give incorrect results. Same with "signed" vs "unsigned" integers - we have to use the appropriate instructions.
It might, in fact, be enlightening to write out the intended operations in vb (or C/C++), whatever language you're familiar with, and "translate" to asm step by step. Code is code.
Best,
Frank
-
It might, in fact, be enlightening to write out the intended operations in vb (or C/C++), whatever language you're familiar with, and "translate" to asm step by step. Code is code.
And if you output the assembly listing using the appropriate compiler switches you can see how the professional tools generate code. It's very enlightening when you have optimizations turned on to guage just how good your compiler's output really is.