Incorrect RAM count with INT 15h

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
smiddy

Re:Incorrect RAM count with INT 15h

Post by smiddy »

When I get home this evening I'll post my code snippit for converting bin to ASCII hex. It was written when I (re)started out writing ASM. It is in FASM syntax, but should be readily convertable to TASM since I do not use macros or anything other than direct assembly code, that is readable. Meaning, I don't do any bit manipulation tricks, straight coding. You'll see this evening (mine that is). ;)
smiddy

Re:Incorrect RAM count with INT 15h

Post by smiddy »

Code: Select all

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ToHex
;; Loads HexBuffer with ASCII corresponding to 8, 16, or 32 bit interger in
;;    hex.
;; Requires interger in AL, AX, or EAX depending on bit size
;; Requires the number of bits in the CL
;; Returns a full buffer or an empty buffer on error
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ToHex32:
    
    push eax
    push ebx

    MOV EBX,0                   ; Load BX with pointer offset
    MOV [TheEAX32],EAX          ; Save the EAX
    MOV [TheCL32],CL            ; Save the CL 
    CMP CL,0x08                 ; Check for 8 bits
    JNE .Check16
    JMP .Loop1                  ; Start loading the buffer

.Check16:

    CMP CL,0x10                 ; Check for 16 bits
    JNE .Check32
    JMP .Loop1                  ; Start loading the buffer

.Check32:

    CMP CL,0x20                 ; Check for 32 bits
    JNE .ErrorBits

.Loop1:

    MOV EAX,[TheEAX32]          ; Reload EAX with the converter
    SUB CL,0x04                 ; Lower bit count by 4 bits
    SHR EAX,CL

    AND AL,0x0F
    ADD AL,'0'
    CMP AL,'9'
    JBE .LoadBuff1
    ADD AL,'A'-'0'-10           ; Convert to "A" to "F"

    JMP .LoadBuff1

.Loop2:

    MOV EAX,[TheEAX32]          ; Reload EAX again
    SUB CL,4                    ; Lower bit count by 8 bits
    SHR EAX,CL
    AND AL,0x0F
    ADD AL,'0'
    CMP AL,'9'
    JBE .LoadBuff2
    ADD AL,'A'-'0'-10           ; Convert A,B,C,D,E,F

    JMP .LoadBuff2

.LoadBuff1:

    MOV [HexBuffer32 + EBX],AL  ; Load buffer with AL
    INC BX                      ; Increment buffer pointer
    JMP .Loop2                  ; Do next byte

.LoadBuff2:

    MOV [HexBuffer32 + EBX],AL  ; Load buffer with AL
    INC EBX                     ; Increment buffer pointer
    CMP CL,0x00                 ; Check if we're done
    JNE .Loop1                  ; Do next Byte 

.ErrorBits:

    MOV AL,0x00
    MOV [HexBuffer32 + EBX],AL       ; End the string with a zero
    
    pop ebx
    pop eax

    RET
I left out the variable declarations...enjoy!
Kemp

Re:Incorrect RAM count with INT 15h

Post by Kemp »

I would use that except mine is exactly 20 lines (including dealing with A-F properly) and it can be used for a number of any length... and it now puts them in the right order :) One minor problem that I need to fix and it's done. It could probably be optimised by someone better than me as well.

Nevertheless, thanks for posting the code, I'll have a look through it properly and see if there's anything I can steal ;D
Kemp

Re:Incorrect RAM count with INT 15h

Post by Kemp »

And with one last annoying problem fixed, here we are:

Code: Select all

bin2hex:
   PUSH ECX
   SHL CX, 1
   SUB CX, 2
   ADD DI, CX
   POP ECX
bin2hexmain:
   LODSB
   MOV AH, AL
   AND AX, 0000111111110000b
   SHR AL, 4

   MOV BX, OFFSET hexTable
   ADD BL, AL
   MOV AL, BYTE PTR [BX]

   MOV BX, OFFSET hexTable
   ADD BL, AH
   MOV AH, BYTE PTR [BX]

   STOSW
   SUB DI, 4
   LOOP bin2hexmain
   RETN
No doubt that's longer than it needs to be, but it works :D :D

You put the number of bytes to convert in ECX, the source address in SI, the destination address in DI, call bin2hex and job done :)
smiddy

Re:Incorrect RAM count with INT 15h

Post by smiddy »

Kemp wrote: I would use that except mine is exactly 20 lines (including dealing with A-F properly) and it can be used for a number of any length... and it now puts them in the right order :) One minor problem that I need to fix and it's done. It could probably be optimised by someone better than me as well.

Nevertheless, thanks for posting the code, I'll have a look through it properly and see if there's anything I can steal ;D
Like I said, this was an attempt over a year ago when I restarted ASM programming. I've change significantly since then, thus the reason it is so huge in comparison. I am leaning towards readability over sheer size these days too, which mean there may always be a shorter/faster way, but it may not be readable. The older I get the more readable it needs to be so that I don't have those senior moments. :D

Go for it...I share most of my code. The syntax is close enough to TASM that you shouldn't have too much of a stretch if you need to change it. Have you seen Solar OS? It is written entirely in TASM and uses JLoc as a linker.

BTW, nice code!
Kemp

Re:Incorrect RAM count with INT 15h

Post by Kemp »

Solar OS was written entirely in TASM? Wow, I'm doing a large portion of mine in that, but I'm switching to C as soon as I can so I don't go insane, lol. I would be able to do it all in TASM but I think I would end up in a nice padded room with the people in white coats ;) Of course, I need to figure out GCC's command line parameters first and how to use a real linker, this is what I get for using IDEs designed for creating Win32 applications, it kinda seperates you from what's really going on.

One thing I don't like about my routine right now is that I have to load the offset of hexTable twice, but TASM wouldn't let me do something like

MOV AH, BYTE PTR [BX + AL]

It's probably me doing it wrong, I guess it allows addressing like that, but you probably can't add a byte register to a word one or something.

Edit:
It occurs to me that I can shorten it down a bit :) My reflex to optimise rather than code more is kicking in ::)

Edit 2:
Actually, forget that idea. Deciding what to do next, my original plan involved pulling as much data as possible out of the BIOS before I lose access going to protected mode, think I'll concentrate on that.
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re:Incorrect RAM count with INT 15h

Post by Solar »

Kemp wrote: Of course, I need to figure out GCC's command line parameters first and how to use a real linker, this is what I get for using IDEs designed for creating Win32 applications, it kinda seperates you from what's really going on.
Go through the BareBones tutorial in the FAQ. That covers most of what you have to know up front about GCC options. Adding -g for debug information and -O2 / -O3 for optimization isn't that difficult either.
One thing I don't like about my routine right now is that I have to load the offset of hexTable twice, but TASM wouldn't let me do something like

MOV AH, BYTE PTR [BX + AL]
What you're looking for is table 2.1, page 32 of the Intel Instruction Set Manual (Vol. 2 of the Intel Manuals). ;) It lists all valid register combinations for getting an effective address.

Basically, you can combine BX or BP with either SI, DI, or a fixed number.

Edit: Note that BX implies DS:BX, and BP implies SS:BP.
Every good solution is obvious once you've found it.
Kemp

Re:Incorrect RAM count with INT 15h

Post by Kemp »

Thanks a lot. The FAQ was going to be the first place I hit for GCC options (and most other things really), I would have been surprised if it didn't mention something like this. And those are very exact directions within the document :) I'll check that out and see what I can do.
Post Reply