Calculating memory address
Code:
1: void __fastcall fastpixel(long* surface)
2: {
3: int iCount = 1152*864;
4: __asm
5: {
6: // Assign pointers to register
7: push edi;
8: push ecx;
9: push eax;
10: mov edi, [surface] ; //put dest addr to edi reg
11: mov ecx, [iCount] ;// put count to ecx reg
12:
13: codeloop:
14: mov eax, [edi] ; //mov a byte of src data to low
15: xor eax, 0x00ffffff ;
16: mov [edi], eax ;
17: add edi,4;
18: dec ecx ; //decrement count by 1
19: jnz codeloop ; //jump to codeloop if not 0
20: pop edi;
21: pop ecx;
22: pop eax;
23: }
24: }
Ok so I've got this lovely bit of code that I've constructed and I need a few clerifications:
in theory I should have been able to replace lines 14 to 16 with this:
first:
xor [edi], 0x00FFFFFF
how ever this just turns my screen blue :\
second:
I seem to need to use add edi,4 instead of just inc because inc only seems to move it 1 byte forward, is there a way to fix this?
third:
This is in the help docs for MASM32 but I have no clue what idex, scale, and displacement are reffering to.
[ Base Address + Index * Scale + Displacement ]
[ebx + ecx * 4 + 8]
ebx is the base address.
ecx is the index.
4 is the scale based on the data size.
8 is the displacement in BYTES.
Re: Calculating memory address
Your function could look like:
Code:
void fastpixel(long* surface)
{
int iCount = 1152*864;
__asm
{
// Assign pointers to register
push edi;
push ecx;
push eax;
mov edi, [surface] ; //put dest addr to edi reg
mov ecx, [iCount] ;// put count to ecx reg
codeloop:
//mov eax, [edi] ; //mov a byte of src data to low
//xor eax, 0x00ffffff ;
//mov [edi], eax ;
xor DWORD PTR [edi+ecx*4-4], 0x00ffffff;
//inc edi
//add edi,4;
dec ecx ; //decrement count by 1
jnz codeloop ; //jump to codeloop if not 0
pop edi;
pop ecx;
pop eax;
}
}
As you see, there is no need to modify EDI, although increasing it by 4 is not worse than increasing by 1, compilers create instructions like 'add reg data_type_size' when processing arrays. You also lack type specifier, thats why your 'xor [edi], long_num' did not work. And, in added line, you have example of addresing with index,scale and displacement.
Unfortunately, at this moment I have no time to explain these changes, but if you do not understand them, I will do it today evening (evening of CET+1h :) ).
Hope it helps
Hob
Re: Calculating memory address
hmm thanks that did help, I'm having another problem though, I have this asm code which for some reason does not work for writing 8bit video memory, instead the middle of my screen generates this image
(resolution is to big to post so you'lk need to use the link, and possibly paint ;) )
http://img.photobucket.com/albums/v5...ul/ASMprob.png
all of those objectes are supposed to be a single thing in the middle not all spread out like that. (9 objects)
Code:
//index = (X-1+((Y-1)*1152));
__asm
{
mov eax, [X];//this ASM replaces the index calulation
sub eax, 1;
mov ecx, [Y];
sub ecx, 1;
imul ecx, 1152;
add ecx,eax;
//mov ecx, [index]; //index
mov edi, [surface]; //put dest addr to edi reg
mov al, [edi+ecx]; //mov a byte of src data to low
xor al, 0xF;
mov [edi+ecx], al;
Re: Calculating memory address
Those ideas are not tested, because I have no compiler here, let me know if it helped:
1. Always when you are reading or storing a value from memory, use size specifier. This does not affect the program, and you will be sure that everything is ok.
2. This code seems to be time-critical for you, or you just like to mess around with assembler. In both cases you could replace 'imul val, 1152' with
Code:
mov val, reg1;
mov val, reg2;
shl reg1, 10;
shl reg2, 7;
add reg1, reg2
Rumours say that xMUL is slower than set of movs/shifts/adds, but i do not know hows that with modern procesors. Besides, IMUL is a bit tricky with it source/dest operands.
Instead 'sub reg,1' you could use 'dec reg'.
Thats all what I can help without compiler, Ill check it for more when i am back home.
Hob
Re: Calculating memory address
I checked your code with compiler and it works in correct way (X and Y should be declared as DWORDS). Probably not index calculation code is your problem. I forgot to mention earlier:
Is 'surface' variable a pointer to memory of DirectX screen surface? If so, you should know that width of DirectX screen surface is NOT equal to its horizontal resolution. In your index calculationd you should use not 1152 (resolution value) but its pitch value.
If its not a DX screen buffer, then your problem is probably located not in index calculation routine. I would expect that X and Y variables are declared as WORD, and in assembly code they are used as DWORD. Just use size specifiers EVERYWHERE where possible. If your problem still persists, attach your project and I will check it (if its not too complicated for me).
Hob.
Re: Calculating memory address
it is a pointer to the screen memory (void pointer), I'm well aware of pitch (surface.lPitch) how ever I have specified a 8 bit screen thus making the pitch 1, on the other prog I use the *4 in the index cause that was 32bit mode, thus I should not need to specify an index multiplier.
Re: Calculating memory address
So if its not pitch, then I'd expect some size mismatch between declaration of coords and their usage in asm code.
By 'size specifier' I did not mean index multiplier. In this case it should be indeed set to 1. I just mean that your function prototype could look like
Code:
void setpixel(void* surf, WORD X, WORD Y)
while in asm snippet you use
what moves into eax 32-bit value.
If it is also not a reason, then I think that trouble is not located at code posted by you.
If you attach your project, it does not need some specific libs and can be compiled under VC 6.0, I might to take look at it.
Hob
1 Attachment(s)
Re: Calculating memory address
This is DDSurfaceDesc.lPitch value in your app. For some reason, it is NOT equal 1. You need to multiply all coords by this pitch, instead of 1152. If you have problem with changes, msg me.
Remember, that lPitch can vary depending on Graphic hardware driver, and it should be read every time it will be used.
Hob
Re: Calculating memory address
I will try pitch as soon as I get home, how ever it seems either you implimented my prog without the same rules or something went wrong because the straight line in your program should not exist, this link shows what you should see starting in the middle of my screen if it works correctly:
http://www.radicaleye.com/lifepage/p...s/rabbits.html
and I thank you for taking the time to help this stubourn noobie :) although I like ASM quite a bit, I'd have to say I love C++/ASM hybrid prorgamming alot.
Re: Calculating memory address
Straight line is made by me, for testing purposes. Your life of rabbits is working correctly, just now you need to change ALL occurences of 1152 to pitch, what will fix coords, because now pixels are spread around whole screen. And i'd suggest not hardcode pitch value, just read it each time when ddsdesc is obtained.
Always to help
Hob
Re: Calculating memory address
heh heh yeah I made a cardinal sin in DirX :) I realised that after a computer at school was experiencing the same glitch in the 32bit working version ;)