Anyone know any good inline assembly functions, grahics or otherwise?
Printable View
Anyone know any good inline assembly functions, grahics or otherwise?
Check this baby out: (I wrote this yesterday)
Just call sound(frequency, duration in 1/100sec). It makes a tone on the PC's internal speaker :)Code:#include <iostream>
#if _MSC_VER < 1100
#error Unlikely to work on another compiler...
#endif
using namespace std;
void sound(long lFreq, long lDuration);
int main() {
for(int j = 1; j < 5; j++) {
for(int i = 1; i < 5; i++) {
sound(1046 / i, 10);
sound(988 / i, 10);
sound(880 / i, 10);
sound(784 / i, 10);
sound(699 / i, 10);
sound(659 / i, 10);
sound(587 / i, 10);
sound(523 / i, 10);
}
}
return 0;
}
void sound(long lFreq, long lDuration) {
__asm {
; Setting up
mov ebx, lDuration
mov edi, lFreq
in al, 61h // Read current port mode B
mov cl, al // Save current mode
or al, 3 // Switch on speaker and timer
out 61h, al
mov al, 0b6h // Set for channel 2
out 43h, al // Command register
mov dx, 14h
mov ax, 4f38h // Frequency divisor
div di
out 42h, al // Low byte of frequency
mov al, ah
out 42h, al // High byte of frequency
; Delay
mov ax, 91 // Multiplier
mul bx
mov bx, 500
div bx
mov bx, ax // Save result
mov ah, 0 // Read time
int 1ah
add dx, bx
mov bx, dx
// Cycle until time's up
Cycle: int 1ah
cmp dx, bx // Has time gone?
ja Break // If we miss it somehow...exit anyway
jne Cycle // Loop round again
Break: in al, 61h // Read mode of port B
mov al, cl // Previous mode
and al, 0fch
out 61h, al // Restore mode
}
}
My favorite! :rolleyes:
WOO! No #includes! :)
It returns one of the error code things defined on the top.Code:#define ASMERROR_SUCCESS 0x00
#define ASMERROR_FUNCTION_NOT_SUPPORTED 0x01
#define ASMERROR_VOLUME_LOCKED 0xB1
#define ASMERROR_VOLUME_NOT_REMOVABLE 0xB2
#define ASMERROR_EJECT_REQUEST_FAILED 0xB5
short AsmEjectDrive(char DriveLetter)
{
short ReturnValue = ASMERROR_SUCCESS;
short DriveNumber = (short) DriveLetter - (DriveLetter>=65 && DriveLetter<=90 ? 64 : 96);
__asm {
push ax
push bx // Preserve registers for later
push cx
mov ax, 440Dh // Generic IOCTL operation
mov bx, DriveNumber // BX register requires drive NUMBER (not letter)
mov cx, 849h // Device operation -> eject something removable!
int 21h // Yep, it's the 21h interrupt we know and love
jnc success // No carry flag? WOO! Success!
mov ReturnValue, ax // Carry flag? DRATS! Failure. AX (ErrorCode)->ReturnValue
success:
pop cx
pop bx // Restore registers (they were preserved)
pop ax
}
// By now, either the drive ejected itself and ReturnValue remained
// ASMERROR_SUCCESS, or it didn't and ReturnValue became one of the
// error codes #defined above... Good enough by us! Return it.
return ReturnValue;
}
void main()
{
AsmEjectDrive('E'); // Guess what this does...
}
Well, my hard disk just flew out of its caddy :). I think it's time for an asm competition...;)
Well I don't really know any cool assembly functions. :(
This one for ejecting your "hard drive", I stole from MSDN when nobody was looking. :rolleyes:
Oh, here's one from around my HD somewhere...
Let's say you don't want a whole huge #include just for a poor little clrscr() - solution:
Use this! :rolleyes:
It's been long, it might not work, you'll get over it. :rolleyes:Code:void clrscr()
{
__asm {
push ax
push es
push di // Save all the junky registers
push cx
mov ax, 0xB800 // Put the video-card address 0xB800 in AX
mov es, ax // ...so that we can move it to ES
xor di, di // Set DI to zero (start clearing the screen from the zeroest point)
mov cx, 2000 // We want to clear 2000 chars (80x25)
mov ax, 20h // Clear with the character 20h (space)
rep stosw // Store 20h in ES:DI (video:changing location) 2000 times, thus CLRSCRing
pop cx
pop di // Take 'em back
pop es
pop ax
}
}
<ahem> speaking of ASM, paste this into an ASM file, and compile it.
incase you dont get a chance to try this totaly kewl program, it makes your moniter in full-screen mode, then makes cool fire effect...
=)
it has nothing to do with what your talking about, I just thought I would include it(BTW the compiled executable is only 1.92kb)
Ok, you called my bluff, you saw an INCLUDE in there,Code:
.MODEL SMALL ; Data segment < 64K, code segment < 64K
.STACK 200H ; Set up 512 bytes of stack space
.386
; ===========================================================================
.DATA
CR EQU 13
LF EQU 10
BufferX EQU 320 ; Width of screen buffer
BufferY EQU 104 ; Height of screen buffer
AllDone DB CR, LF, "That was:"
DB CR, LF
DB CR, LF, " FFFFFFFFF IIIIIII RRRRRRRRR EEEEEEEEE ! "
DB CR, LF, " FFF III RRR RRR EEE !!! "
DB CR, LF, " FFF III RRR RRR EEE !!!!!"
DB CR, LF, " FFF III RRRRRRRR EEE !!!!!"
DB CR, LF, " FFFFFFF III RRRRRRRR EEEEEEEE !!!!!"
DB CR, LF, " FFF III RRR RRR EEE !!! "
DB CR, LF, " FFF III RRR RRR EEE "
DB CR, LF, " FFF III RRR RRR EEE !!! "
DB CR, LF, " FFFFF IIIIIII RRRR RRRR EEEEEEEEE !!! "
DB CR, LF
DB CR, LF
Buffer DB BufferX * BufferY DUP (?) ; The screen buffer
Seed DW 3749h
INCLUDE PALETTE.DAT ; The palette, generated with
; Autodesk Animator, and a simple
; Pascal program.
; ===========================================================================
.CODE
InitializeMCGA PROC
MOV AX, 0A000h
MOV ES, AX ; ES now points to the VGA
MOV AH, 00H ; Set video mode
MOV AL, 13H ; Mode 13h
INT 10H ; We are now in 320x200x256
RET
InitializeMCGA ENDP
; ---------------------------------------------------------------------------
SetUpPalette PROC
MOV SI, OFFSET Palette ; SI now points to the palette
MOV CX, 768 ; Prepare for 768 OUTs
MOV DX, 03C8H ; Palette WRITE register
XOR AL, AL ; Start at color 0
CLI ; Disable interrupts
OUT DX, AL ; Send value
CLD ; Forward direction
INC DX ; Now use palette DATA register
REP OUTSB ; 768 multiple OUTs
STI ; Enable interrupts
RET
SetupPalette ENDP
; ---------------------------------------------------------------------------
; This procedure was picked up from comp.lang.asm.x86 - many thanks to the
; unknown author.
Random PROC
MOV AX, Seed ; Move the seed value into AX
MOV DX, 8405H ; Move 8405H into DX
MUL DX ; Put 8405H x Seed into DX:AX
INC AX ; Increment AX
MOV Seed, AX ; We have a new seed
RET
Random ENDP
; ---------------------------------------------------------------------------
DrawScreen PROC
MOV SI, OFFSET Buffer ; Point SI to the start of the buffer
XOR DI, DI ; Start drawing at 0, 0
MOV BX, BufferY - 4 ; Miss the last four lines from the
; buffer. These lines will not look
; fire-like at all
Row:
MOV CX, BufferX SHR 1 ; 160 WORDS
REP MOVSW ; Move them
SUB SI, 320 ; Go back to the start of the array row
MOV CX, BufferX SHR 1 ; 160 WORDS
REP MOVSW ; Move them
DEC BX ; Decrease the number of VGA rows left
JNZ Row ; Are we finished?
RET
DrawScreen ENDP
; ---------------------------------------------------------------------------
AveragePixels PROC
MOV CX, BufferX * BufferY - BufferX * 2 ; Alter all of the buffer,
; except for the first row and
; last row
MOV SI, OFFSET Buffer + 320 ; Start from the second row
Alter:
XOR AX, AX ; Zero out AX
MOV AL, DS:[SI] ; Get the value of the current pixel
ADD AL, DS:[SI+1] ; Get the value of pixel to the right
ADC AH, 0
ADD AL, DS:[SI-1] ; Get the value of pixel to the left
ADC AH, 0
ADD AL, DS:[SI+BufferX] ; Get the value of the pixel underneath
ADC AH, 0
SHR AX, 2 ; Divide the total by four
JZ NextPixel ; Is the result zero?
DEC AX ; No, so decrement it by one
NextPixel:
MOV DS:[SI-BufferX], AL ; Put the new value into the array
INC SI ; Next pixel
DEC CX ; One less to do
JNZ Alter ; Have we done them all?
RET
AveragePixels ENDP
; ---------------------------------------------------------------------------
TextMode PROC
MOV AH, 00H ; Set video mode
MOV AL, 03H ; Mode 03h
INT 10H ; Enter 80x25x16 mode
MOV DX, OFFSET AllDone ; DS:DX points to the ending message
MOV AH, 09H
INT 21H ; Display the ending message
RET
TextMode ENDP
; ---------------------------------------------------------------------------
Start:
MOV AX, @DATA
MOV DS, AX ; DS now points to the data segment.
CALL InitializeMCGA
CALL SetUpPalette
MainLoop:
CALL AveragePixels
MOV SI, OFFSET Buffer + BufferX * BufferY - BufferX SHL 1
; SI now points to the start of the second last row
MOV CX, BufferX SHL 1 ; Prepare to get BufferX x 2 random #s
BottomLine:
CALL Random ; Get a random number
MOV DS:[SI], DL ; Use only the low byte of DX - ie,
INC SI ; the number will be 0 --> 255
DEC CX ; One less pixel to do
JNZ BottomLine ; Are we done yet?
CALL DrawScreen ; Copy the buffer to the VGA
MOV AH, 01H ; Check for keypress
INT 16H ; Is a key waiting in the buffer?
JZ MainLoop ; No, keep on going
MOV AH, 00H ; Yes, so get the key
INT 16H
CALL TextMode
MOV AH, 4CH
MOV AL, 00H
INT 21H ; Return to DOS
END Start
put this in a file called pallete.dat
Code:; This file was generated externally by a high level language, and a
; copy of Autodesk Animator. This file is only needed by FIRE!.ASM
; during assembly, and is not required for FIRE!.EXE to run.
Palette DB 0, 0, 0, 0, 0, 6, 0, 0, 6, 0, 0, 7, 0, 0, 8, 0, 0, 8, 0, 0, 9, 0, 0, 10
DB 2, 0, 10, 4, 0, 9, 6, 0, 9, 8, 0, 8, 10, 0, 7, 12, 0, 7, 14, 0, 6, 16, 0, 5
DB 18, 0, 5, 20, 0, 4, 22, 0, 4, 24, 0, 3, 26, 0, 2, 28, 0, 2, 30, 0, 1, 32, 0, 0
DB 32, 0, 0, 33, 0, 0, 34, 0, 0, 35, 0, 0, 36, 0, 0, 36, 0, 0, 37, 0, 0, 38, 0, 0
DB 39, 0, 0, 40, 0, 0, 40, 0, 0, 41, 0, 0, 42, 0, 0, 43, 0, 0, 44, 0, 0, 45, 0, 0
DB 46, 1, 0, 47, 1, 0, 48, 2, 0, 49, 2, 0, 50, 3, 0, 51, 3, 0, 52, 4, 0, 53, 4, 0
DB 54, 5, 0, 55, 5, 0, 56, 6, 0, 57, 6, 0, 58, 7, 0, 59, 7, 0, 60, 8, 0, 61, 8, 0
DB 63, 9, 0, 63, 9, 0, 63, 10, 0, 63, 10, 0, 63, 11, 0, 63, 11, 0, 63, 12, 0, 63, 12, 0
DB 63, 13, 0, 63, 13, 0, 63, 14, 0, 63, 14, 0, 63, 15, 0, 63, 15, 0, 63, 16, 0, 63, 16, 0
DB 63, 17, 0, 63, 17, 0, 63, 18, 0, 63, 18, 0, 63, 19, 0, 63, 19, 0, 63, 20, 0, 63, 20, 0
DB 63, 21, 0, 63, 21, 0, 63, 22, 0, 63, 22, 0, 63, 23, 0, 63, 24, 0, 63, 24, 0, 63, 25, 0
DB 63, 25, 0, 63, 26, 0, 63, 26, 0, 63, 27, 0, 63, 27, 0, 63, 28, 0, 63, 28, 0, 63, 29, 0
DB 63, 29, 0, 63, 30, 0, 63, 30, 0, 63, 31, 0, 63, 31, 0, 63, 32, 0, 63, 32, 0, 63, 33, 0
DB 63, 33, 0, 63, 34, 0, 63, 34, 0, 63, 35, 0, 63, 35, 0, 63, 36, 0, 63, 36, 0, 63, 37, 0
DB 63, 38, 0, 63, 38, 0, 63, 39, 0, 63, 39, 0, 63, 40, 0, 63, 40, 0, 63, 41, 0, 63, 41, 0
DB 63, 42, 0, 63, 42, 0, 63, 43, 0, 63, 43, 0, 63, 44, 0, 63, 44, 0, 63, 45, 0, 63, 45, 0
DB 63, 46, 0, 63, 46, 0, 63, 47, 0, 63, 47, 0, 63, 48, 0, 63, 48, 0, 63, 49, 0, 63, 49, 0
DB 63, 50, 0, 63, 50, 0, 63, 51, 0, 63, 52, 0, 63, 52, 0, 63, 52, 0, 63, 52, 0, 63, 52, 0
DB 63, 53, 0, 63, 53, 0, 63, 53, 0, 63, 53, 0, 63, 54, 0, 63, 54, 0, 63, 54, 0, 63, 54, 0
DB 63, 54, 0, 63, 55, 0, 63, 55, 0, 63, 55, 0, 63, 55, 0, 63, 56, 0, 63, 56, 0, 63, 56, 0
DB 63, 56, 0, 63, 57, 0, 63, 57, 0, 63, 57, 0, 63, 57, 0, 63, 57, 0, 63, 58, 0, 63, 58, 0
DB 63, 58, 0, 63, 58, 0, 63, 59, 0, 63, 59, 0, 63, 59, 0, 63, 59, 0, 63, 60, 0, 63, 60, 0
DB 63, 61, 0, 63, 61, 0, 63, 61, 0, 63, 62, 0, 63, 62, 0, 63, 62, 0, 63, 62, 0, 63, 63, 0
DB 63, 63, 1, 63, 63, 2, 63, 63, 3, 63, 63, 4, 63, 63, 5, 63, 63, 6, 63, 63, 7, 63, 63, 8
DB 63, 63, 9, 63, 63, 10, 63, 63, 10, 63, 63, 11, 63, 63, 12, 63, 63, 13, 63, 63, 14, 63, 63, 15
DB 63, 63, 16, 63, 63, 17, 63, 63, 18, 63, 63, 19, 63, 63, 20, 63, 63, 21, 63, 63, 21, 63, 63, 22
DB 63, 63, 23, 63, 63, 24, 63, 63, 25, 63, 63, 26, 63, 63, 27, 63, 63, 28, 63, 63, 29, 63, 63, 30
DB 63, 63, 31, 63, 63, 31, 63, 63, 32, 63, 63, 33, 63, 63, 34, 63, 63, 35, 63, 63, 36, 63, 63, 37
DB 63, 63, 38, 63, 63, 39, 63, 63, 40, 63, 63, 41, 63, 63, 42, 63, 63, 42, 63, 63, 43, 63, 63, 44
DB 63, 63, 45, 63, 63, 46, 63, 63, 47, 63, 63, 48, 63, 63, 49, 63, 63, 50, 63, 63, 51, 63, 63, 52
DB 63, 63, 52, 63, 63, 53, 63, 63, 54, 63, 63, 55, 63, 63, 56, 63, 63, 57, 63, 63, 58, 63, 63, 59
DB 63, 63, 60, 63, 63, 61, 63, 63, 62, 63, 63, 63, 63, 63, 60, 63, 63, 61, 63, 63, 62, 63, 63, 63
Does anyone have any asm functions for plotting s pixel, and drawing a line and rectangle?
Ok i found a bunch of functions in asm, but the ones that have a variable thats a "byte" dont seem to work. What i mean by byte is...
void pixel(int x, int y, byte color)
Any ideas?
How is it used?
and does it give an error as to say why it doesnt work??
Here's the definition:
Good luck! :rolleyes:Code:typedef __int8 byte;
This is the function...
void pixel(int x, int y, byte color)
{
asm mov ax, 0A000h
asm mov es, ax
asm mov bx, x
asm mov dx, y
asm xchg dh, dl
asm mov al, color
asm mov di, dx
asm shr di, 2
asm add di, dx
asm add di, bx
asm stosb
}
Do you see anything wrong in it?
I dont really know how ASM works in C++, but I dont think you need the asm in front of everything.
The syntax is:
orCode:asm statement
In Visual C++, though, you need to use __asm rather than asm.Code:asm {
statements
}
PS: Dennis - I'm back on YM now, if you wanted to talk.
If you didnt notice, i have "asm" in front of everything.
Yeah - I was just clarifying for Dennis...:)
I don't see anything wrong with that code.
Is it not working? :rolleyes:
It didn't work on my copy of VC++5...until I added this to the top of the file:
That should work for most compilers, since they usually add a __ to proprietary things.Code:#ifndef asm
#define asm __asm
#endif
Well i think i got past that byte problem, but now im getting this error...
Error: 286/287 instructions not enabled in function pixel(int, int, unsigned char)
Any ideas?
What compiler / error number?
I figured it out, i have to compile with the 286 instructions tirned on. It was all my fault, i should have looked at the switches sooner. Thanks though. One more questions, does anyone know how to draw a line, square and circle?
Or if you dont know any could you transfer these into inline assembly for me, thanks.
Code:void line(int x1, int y1, int x2, int y2, byte color)
{
int i, dx, dy, sdx, sdy, dxabs, dyabs, x, y, px, py;
dx = x2 - x1;
dy = y2 - y1;
dxabs = abs(dx);
dyabs = abs(dy);
sdx = sgn(dx);
sdy = sgn(dy);
x = dyabs>>1;
y = dxabs>>1;
px = x1;
py = y1;
VGA[(py<<8)+(py<<6)+px]=color;
if(dxabs >= dyabs)
{
for(i = 0; i < dxabs; i++)
{
y+=dyabs;
if(y >= dxabs)
{
y-+dxabs;
py+=sdy;
}
px+=sdx;
pixel(px, py, color);
}
}
else
{
for(i = 0; i < dyabs; i++)
{
x+=dxabs;
if(x >= dyabs)
{
x-=dyabs;
px+=sdx;
}
py+=sdy;
pixel(px, py, color);
}
}
}
Code:void rect(int left, int top, int right, int bottom, byte color)
{
word top_offset, bottom_offset, i, temp;
if(top>bottom)
{
temp=top;
top=bottom;
bottom=temp;
}
if(left>right)
{
temp=left;
left=right;
right=temp;
}
top_offset=(top<<8)+(top<<6);
bottom_offset=(bottom<<8)+(bottom<<6);
for(i=left; i<=right; i++)
{
VGA[top_offset+i]=color;
VGA[bottom_offset+i]=color;
}
for(i=top_offset; i<=bottom_offset; i+=SCREEN_WIDTH)
{
VGA[left+i]=color;
VGA[right+i]=color;
}
}
Code:void rectFill(int left, int top, int right, int bottom, byte color)
{
word top_offset, bottom_offset, i, temp, width;
if(top>bottom)
{
temp=top;
top=bottom;
bottom=temp;
}
if(left>right)
{
temp=left;
left=right;
right=temp;
}
top_offset=(top<<8)+(top<<6)+left;
bottom_offset=(bottom<<8)+(bottom<<6)+left;
width=right-left+1;
for(i=top_offset; i<=bottom_offset; i+=SCREEN_WIDTH)
{
memset(&VGA[i], color, width);
}
}
I really hope this doesn't work, because that would mean I know asm! :rolleyes:
Code:void line(int x1, int y1, int x2, int y2, byte color)
{
// Changed dx to d_x (dx->register name) and dy to d_y (to look good)
int i, d_x, d_y, sdx, sdy, dxabs, dyabs, x, y, px, py;
asm {
// d_x = x2 - x1;
mov d_x,x2
sub d_x,x1
// dy = y2 - y1;
mov d_y,y2
sub d_y,y1
// dxabs = abs(d_x);
// sdx = sgn(d_x);
mov dxabs,d_x
mov sdx,1
cmp dxabs,0
jge no_neg_d_x
neg dxabs
mov sdx,-1
no_neg_d_x:
// dyabs = abs(d_y);
// sdy = sgn(dy);
mov dyabs,d_y
mov sdy,1
cmp dyabs,0
jge no_neg_d_y
neg dyabs
mov sdy,-1
no_neg_d_y:
// x = dyabs>>1;
mov x,dyabs shr 1
// y = dxabs>>1;
mov y,dxabs shr 1
// px = x1;
mov px,x1
// py = y1;
mov py,y1
// VGA[(py<<8)+(py<<6)+px]=color;
mov ax,A000h
mov es,ax
mov di,x1
add di,y1 shl 6
add di,y1 shl 8
mov al,color
stosb
// if(dxabs >= dyabs)
cmp dxabs,dyabs
jl else_label
// {
// for(i = 0; i < dxabs; i++)
mov cx,dxabs
for_label:
// {
// y+=dyabs;
add y,dyabs
// if(y >= dxabs)
cmp y,dxabs
jl end_inner_if_label
// {
// y-=dxabs;
sub y,dxabs
// py+=sdy;
add py,sdy
// }
end_inner_if_label:
// px+=sdx;
add px,sdx
// pixel(px, py, color);
// NOTE: Standard ASM method------>
push px // Delete these 4 lines if it's
push py // MASM32
push color
call pixel
// NOTE: MASM32 method------------>
invoke pixel,px,py,color // Delete this line if it's not MASM32
dec cx
jnz for_label
// }
jmp end_if_label
// } else {
else_label:
// for(i = 0; i < dyabs; i++)
mov cx,dyabs
other_for_label:
// {
// x+=dxabs;
add x,dxabs
// if(x >= dyabs)
cmp x,dyabs
jl end_other_inner_if_label
// {
// x-=dyabs;
sub x,dyabs
// px+=sdx;
add px,sdx
// }
end_other_inner_if_label:
// py+=sdy;
add py,sdy
// pixel(px, py, color);
// NOTE: Standard ASM method------>
push px // Delete these 4 lines if it's
push py // MASM32
push color
call pixel
// NOTE: MASM32 method------------>
invoke pixel,px,py,color // Delete this line if it's not MASM32
dec cx
jnz other_for_label
// }
// }
end_if_label:
} }
Same goes for this code, I hope it doesn't work! :rolleyes:
Code:void rect(int left, int top, int right, int bottom, byte color)
{
word top_offset, bottom_offset; //, i, temp; ("i" and "temp" not needed in asm)
__asm {
// if(top>bottom)
cmp top,bottom
jle end_first_if
// {
// temp=top;
// top=bottom;
// bottom=temp;
xchg top,bottom
// }
end_first_if:
// if(left>right)
cmp left,right
jle end_second_if
// {
// temp=left;
// left=right;
// right=temp;
xchg left,right
// }
end_second_if:
// top_offset=(top<<8)+(top<<6);
mov top_offset,top shl 8
add top_offset,top shl 6
// bottom_offset=(bottom<<8)+(bottom<<6);
mov bottom_offset,bottom shl 8
add bottom_offset,bottom shl 6
// The following 2 lines are necessary for VGA, and aren't taking from C++ code:
mov ax,A000h
mov es,ax
// The above 2 lines, yadda yadda yadda
// In the C++ statements below, there are numerous VGA[?] = color
// "color" doesn't change so let's put it in AL once, to save lots of time.
mov al,color
// for(i=left; i<=right; i++)
mov cx,right
sub cx,left
// {
first_for_label:
// VGA[top_offset+i]=color;
mov di,top_offset
add di,cx
add di,left // because cx=i-left
stosb
// VGA[bottom_offset+i]=color;
mov di,bottom_offset
add di,cx
add di,left // same reason as above
stosb
// }
dec cx
jnz first_for_label
// for(i=top_offset; i<=bottom_offset; i+=SCREEN_WIDTH)
mov cx,bottom_offset
sub cx,top_offset
// {
second_for_label:
// VGA[left+i]=color;
mov di,left
add di,cx
add di,top_offset
stosb
// VGA[right+i]=color;
mov di,left
add di,cx
add di,bottom_offset
stosb
// }
sub cx,SCREEN_WIDTH
cmp cx,0
jle second_for_label
}
}
ok, i have a function and i want to return the value that in the register AL, how would i do that?
Two ways:
...or...Code:long myfunc(long in) {
long retval;
asm {
mov eax, in
mov retval, eax
}
return retval;
}
In the second case it automatically returns the value. In 32bit C/C++, the return value is always stored in EAX.Code:long myfunc(long in) {
asm {
mov eax, in
}
}
The problem with that is im using dos so i cant use 32-bit registers.
Umph...
Try using AX then, for the return value. Keep in mind, though, that AH and AL are the high and low bytes of AX, and EAX is AX and an extra 16 bits.
Although, I think using it that way should work normally even in 32bit code, as long as nothing too big gets put through.