Absolute Assembler problem

If you have questions about any aspect of QBasic programming, or would like to help fellow programmers solve their problems, check out this board!

Moderators: Pete, Mods

Post Reply
apefish
Newbie
Posts: 2
Joined: Fri Dec 07, 2007 7:57 pm

Absolute Assembler problem

Post by apefish »

Hi, im having some trouble getting absolute assembler to work. I got V2.1 form teh tutorials page and tried to make it work. But it locks up on the first SHELL command. I got the path for debug correct down to every character including case. Using debug manually seems to work but its super tedius as you cant even copy/paste so i make typing errors etc that generate errors. For some of the stuff i have layed out i need the line label support and general quickness. Also, im using QBasic on win98 and xp, if that changes anything. is there somethign wrong with this version, or somethign i missed? And are there any other programs that do assembler-to-basic string? It woudl sure be nice to have those line labels...
any help is appreciated.
Ralph
Veteran
Posts: 148
Joined: Fri Feb 09, 2007 3:10 pm
Location: Katy, Texas

QB Assembler

Post by Ralph »

Don't know if this will help you, but, if you download QuickBASIC 4.5, you will be able to compile most code directly from the IDE.
Ralph, with QuickBASIC 4.5, operating under Windows XP, wiht anHP LaserJet 4L Printer. Bilingual in English/Spanish
apefish
Newbie
Posts: 2
Joined: Fri Dec 07, 2007 7:57 pm

Post by apefish »

well then that sounds good, why havent I heard of this before? do you mean assemble or compile? i want to assemble into those string input lines that are used for CALL ABSOLUTE. i will download QB4.5 anyways but i dont think QB does assembler except through call absolute. so i still need to get absolute assembler to work or get an equivalent program.
Ralph
Veteran
Posts: 148
Joined: Fri Feb 09, 2007 3:10 pm
Location: Katy, Texas

Assembler

Post by Ralph »

Yes, you're right. I don't know why I confused assemlbe with compile! QuickBASIC 4.5 makes compiling very easy, not the assembler thing. I, personally, just barely got into assebly language, but have never done anything with it. I hear that QuickBASIC can link (?) with assembly-language code to do a number of things, and, there are folk in the QB forums that about it, but, I am really out of it. Sorry...
Ralph, with QuickBASIC 4.5, operating under Windows XP, wiht anHP LaserJet 4L Printer. Bilingual in English/Spanish
User avatar
Michael Calkins
Veteran
Posts: 76
Joined: Tue Apr 05, 2005 8:40 pm
Location: Floresville, Texas
Contact:

Post by Michael Calkins »

I'm not sure exactly what you are trying to do... You have an assembly routine already written, and you're trying to include it into your QBASIC program? This is relatively easy. You have it in your program already, and you're trying to debug it by shelling to Debug? This is trickier.

In Windows, you can copy and paste from and to DOS windows. In 98 this is easy; you should have a toolbar with buttons on your console window. In XP, you can right click the title bar of your DOS menu. Also, you can redirect input when you run debug, but only do this if you know what you are doing.

I recommend using the FreeDOS version of Debug. It supports 32 bit instructions.

Do you have Nasm yet? It is a free (LGPL) assembler, and it is very useful.

>line label support

Please clarify. Do you mean symbols in Nasm source?

You might take a look through this thread:
http://www.network54.com/Forum/171757/m ... 067704622/

Once you have the binary assembled code (either from Debug or Nasm), you can include it in your QBASIC program in several ways...

Take as an example one of the hello world examples in that thread I just referred to. The Nasm source is:

Code: Select all

;assemble in nasm
org 0x0 ;origin for nasm

;we need an absolute near address for the display string function, but we don't know where QBASIC has placed this code.

call _next
_next:
;this will be encoded with a relative offset (0x0), so will work. It places the return address on the stack. The return address in this case is the same as the destination address, the address of the _next label.

pop bx
;now we recover that address from the stack. We now know the absolute near address of the _next label.

sub bx,byte _next
;this gives us the absolute near address of the beginning of the code in QBASIC's memory. We will calculate the absolute addresses of other labels by adding this value from the addresses generated by nasm, which are based on an origin of 0x0.

mov dx,_text
add dx,bx ;explained above
mov ah,0x9
int 0x21
retf
_text:
db "Hello, world!",0xd,0xa,"$"
You can generate the same file by typing/pasting exactly this into FreeDOS Debug (must be modified for MS-DOS Debug):

Code: Select all

n hello.bin
r cx 21
a 100
call 103
pop bx
sub bx,3
mov dx,11
add dx,bx
mov ah,9
int 21
retf
db "Hello, world!",d,a,"$"

w
q

either way, you should create a binary file with this content in hex:
E8 00 00 5B 83 EB 03 BA 11 00 01 DA B4 09 CD 21 CB 48 65 6C 6C 6F 2C 20 77 6F 72 6C 64 21 0D 0A 24

Now, you can use those hex values in your QBASIC program like this, or some other way:

Code: Select all

DEFINT A-Z
CONST l = 33
DIM c AS STRING * l
DIM t AS STRING
DIM i AS INTEGER

t = "E800005B83EB03BA110001DAB409CD21CB48656C6C6F2C20776F726C64210D0A24"

IF LEN(t) <> (l * 2) THEN SYSTEM 'just an unneccessary safeguard

FOR i = 0 TO l - 1
MID$(c, i + 1, 1) = CHR$(VAL("&h" + MID$(t, i * 2 + 1, 2)))
NEXT i

CLS

DEF SEG = VARSEG(c)
CALL absolute(VARPTR(c))
To view the code in Debug after it has been loaded by QBASIC, you can do something like this:

PRINT HEX$(VARSEG(c)); ":"; HEX$(VARPTR(c))
SHELL "debug" 'FreeDOS debug

Then type:
r cs whateversegment
u whateveroffset

example screen:

Code: Select all

4511:7EDE
-r cs 4511
-u 7ede
4511:7EDE E80000        CALL    7EE1
4511:7EE1 5B            POP     BX
4511:7EE2 83EB03        SUB     BX,+03
4511:7EE5 BA1100        MOV     DX,0011
4511:7EE8 01DA          ADD     DX,BX
4511:7EEA B409          MOV     AH,09
4511:7EEC CD21          INT     21
4511:7EEE CB            RETF
4511:7EEF 48            DEC     AX
4511:7EF0 65            SEG     GS (unused)
4511:7EF1 6C            INSB
4511:7EF2 6C            INSB
4511:7EF3 6F            OUTSW
4511:7EF4 2C20          SUB     AL,20
4511:7EF6 776F          JA      7F67
4511:7EF8 726C          JB      7F66
4511:7EFA 64210D        AND     FS:[DI],CX
4511:7EFD 0A24          OR      AH,[SI]
-
If you set the registers correctly, you could procede through the code, but be careful not to execute the retf.

If you still have trouble, please post your code, both QBASIC and assembly.

Regards,
Michael
Bring on the Maulotaurs! oops...
I like to slay Disciples of D'Sparil...
User avatar
Stoves
Veteran
Posts: 101
Joined: Fri Feb 10, 2006 12:24 am
Location: Nashville, TN

Post by Stoves »

Never done much with this myself, but...

From "Assembly in QBasic"
by Aaron Severn
December 22, 1997

Using Debug to Generate Machine Code
--------------------------------------

In your DOS directory (or your WINDOWS/COMMAND directory for Windows 95
users) you will find a nice little program called DEBUG.EXE. This is
probably the most user unfriendly piece of software ever created. If you've
tried running it you'll notice that you get the following prompt and nothing
else:

-

So what use is that? Well try typing in the letter 'a' and hitting enter.
Now you've got just as ugly a screen staring back at you that looks
something like this:

-a
199D:0100

But at least we're getting somewhere. You see, 'a' (which stands for
assemble, I think) turns DEBUG into a crude assembler. You can now start
typing in assembly code. As an example, let's try something simple like
turning the mouse on. Here's the assembly code:

push ax
xor ax,ax
int 33
mov ax,1
int 33
pop ax
retf

Enter this code in DEBUG, when you're done enter a blank line, you've just
written a simple assembly program. When you enter the blank line at the end
it should take you back to the dash prompt. Now enter a 'u' (for unassemble)
at the prompt. A whole bunch of weird lines pour out, but wait, there's
that program we just wrote, and beside it, machine code. There should be
four columns on your screen, the first one lists the memory address of each
bit of code, the second one lists the machine code, the third lists the
assembly command, and the fourth lists the arguments for that command. The
column we want is the second one, copy down those numbers that came out,
you should get this.

50
31C0
CD33
B80100
CD33
58
CB

All those numbers are in hex, so in QBasic you'll have to add the &H
prefix.

So now we've got our machine code and we just have to get out of DEBUG.
Type 'q' at the prompt and we'll move on to implementing this in QBasic.

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

Using Machine Code in QBasic
------------------------------

Chances are you already know that CALL ABSOLUTE is the command we need to
use here. This is how you do it. First take the numbers that you copied
down that are the machine code for our little mouse program and put them
together in a string. You want to take the ASCII character associated with
each number, that way we'll have a string of bytes in memory accessible by
CALL ABSOLUTE. Your QBasic code should look something like this:

DIM ASM AS STRING

ASM = ASM + CHR$(&H50)
ASM = ASM + CHR$(&H31) + CHR$(&HC0)
ASM = ASM + CHR$(&HCD) + CHR$(&H33)
ASM = ASM + CHR$(&HB8) + CHR$(&H1) + CHR$(&H0)
ASM = ASM + CHR$(&HCD) + CHR$(&H33)
ASM = ASM + CHR$(&H58)
ASM = ASM + CHR$(&HCB)

Now all you have to do is run it. First set the default segment to the
segment address of ASM, then use CALL ABSOLUTE with the offset address of
ASM as the parameter. Add the following two lines to the bottom of the
above code and then run it.

DEF SEG = VARSEG(ASM)
CALL ABSOLUTE(SADD(ASM)
User avatar
burger2227
Veteran
Posts: 2466
Joined: Mon Aug 21, 2006 12:40 am
Location: Pittsburgh, PA

Face it Ralph

Post by burger2227 »

You probably forgot more than you knew by now. You seem to be a newbie at times and just FALL into stuff you have never had a clue about!

Like links that were highlighted one day and they are not marked later?

Making comments in QB w/o using REM or ' ? Give us all a break buddy

Ted
Please acknowledge and thank members who answer your questions!
QB64 is a FREE QBasic compiler for WIN, MAC(OSX) and LINUX : https://www.qb64.org/forum/index.php
Get my Q-Basics demonstrator: https://www.dropbox.com/s/fdmgp91d6h8ps ... s.zip?dl=0
Post Reply