|
Member 4194593 wrote: Don't tell me MS
OK I won't - you clearly know they are the only ones who can do anything about it. Not that they will...
Member 4194593 wrote: don't ask why not
Can I ask why we shouldn't ask why not? And if not, can I ask why we shouldn't ask why we shouldn't ask why not?
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
|
|
|
|
|
MS will not fix 9.0, they will tell me to buy a newer version, and that version will have new errors for me to find. I do not even want their Express versions for the same reason - new errors to discover.
I just want to warn programmers to watch out for this hard to find error.
Dave.
|
|
|
|
|
Have you been at the Kool Aid again Griff?
Life is like a s**t sandwich; the more bread you have, the less s**t you eat.
|
|
|
|
|
It's a PITA to chop and line up for snorting...
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
|
|
|
|
|
What is MASM? You sure it isn't SPASM?
There are only 10 types of people in the world, those who understand binary and those who don't.
|
|
|
|
|
Hmm, is it a mutation of a woodpecker gene?
|
|
|
|
|
You joke, but there are at least 3 different assemblers actually named SPASM.
|
|
|
|
|
As far as it is not SPAM...
M.D.V.
If something has a solution... Why do we have to worry about?. If it has no solution... For what reason do we have to worry about?
Help me to understand what I'm saying, and I'll explain it better to you
Rating helpful answers is nice, but saying thanks can be even nicer.
|
|
|
|
|
Member 4194593 wrote: Don't tell me MS Well, there's nowhere else of any use.
Member 4194593 wrote: and don't ask why not The answer's obvious.
|
|
|
|
|
I think you could've explained it by now.
I built a component with MASM which calls op code
mov eax, [ebx]
When it executes the processor melts. Maybe something like that. Keep it interesting and we'll read it.
Good luck.
|
|
|
|
|
Thank you for the invitation.
Just a warning to all.
I had a function which had always been working. I modified it to align a short loop (added ALIGN OWORD). The function fails to function correctly (did not cause an error - just bad results which caused other errors - quite difficult to determine just what was happening). The data was 8 DWORDS which were all 0 except most significant which was 40000000h, and I was subtracting a single DWORD with a value of 1. I expected to get 7 DWORDS of FFFFFFFFh and the most significant DWORD with 3FFFFFFFh:
This is the source code:
;*******************************************************************************
;
; SUB a LONG_NUMB value from another. This is a routine called to subtract a
; long number from another after all scaling and validations have been done.
;
; esi has the source OFFSET of the data.
; edi has the already scaled OFFSET of the destination data.
; ecx has the DWORD count to subtract.
;
; Returns nothing with edi pointing to the last word modified. Note that this
; may not be the highest DWORD in the destination if a short source is
; subtracted from a long destination and there are no borrows past the last
; DWORD in the destination or source. This is primarily a check for a size
; extension due to a final borrow.
;
;*******************************************************************************
ALIGN OWORD
SUBIt PROC PRIVATE USES eax ebx esi
pushfd
clc
;
; subtract all the value DWORDS.
;
ALIGN OWORD
DoAll:
mov ebx,[esi]
lea esi,[esi + (SIZEOF DWORD)]
sbb [edi],ebx
lea edi,[edi + (SIZEOF DWORD)]
dec ecx
jnz DoAll
jnc Exit
mov eax,0
;
; Propogate the borrow.
;
ALIGN OWORD
Again:
sbb [edi],eax
lea edi,[edi + (SIZEOF DWORD)]
jc Again
;
; Exit SUBIt, adjust the destination pointer to the last modified DWORD.
;
Exit:
sub edi,(SIZEOF DWORD)
popfd
test dTestZero,0
ret
SUBIt ENDP
This is the generated code from MASM 9.0 (Visual Studio "Disassembly" tab):
ALIGN OWORD
SUBIt PROC PRIVATE USES eax ebx esi
00404FC0 push eax
00404FC1 push ebx
00404FC2 push esi
pushfd
00404FC3 pushfd
clc
00404FC4 clc
00404FC5 lea esp,[esp]
00404FCC lea esp,[esp]
;
; subtract all the value DWORDS.
;
ALIGN OWORD
DoAll:
mov ebx,[esi]
00404FD0 mov ebx,dword ptr [esi]
lea esi,[esi + (SIZEOF DWORD)]
00404FD2 lea esi,[esi+4]
sbb [edi],ebx
00404FD5 sbb dword ptr [edi],ebx
lea edi,[edi + (SIZEOF DWORD)]
00404FD7 lea edi,[edi+4]
dec ecx
00404FDA dec ecx
jnz DoAll
00404FDB jne DoAll (404FD0h)
jnc Exit
00404FDD jae Exit (404FF7h)
mov eax,0
00404FDF mov eax,0
00404FE4 lea esp,[esp] ************************** alignment inserted instructions
00404FEB add eax,0 ****************************** think this might reset the carry Flag?
;
; Propogate the borrow.
;
ALIGN OWORD ***************************************** just added this to help speed up the code
Again:
sbb [edi],eax
00404FF0 sbb dword ptr [edi],eax **************** and cause the SBB here to fail?
lea edi,[edi + (SIZEOF DWORD)]
00404FF2 lea edi,[edi+4]
jc Again
00404FF5 jb Again (404FF0h)
;
; Exit SUBIt, adjust the destination pointer to the last modified DWORD.
;
Exit:
sub edi,(SIZEOF DWORD)
00404FF7 sub edi,4
popfd
00404FFA popfd
test dTestZero,0
00404FFB test dword ptr [dTestZero (40C6BCh)],0
ret
00405005 pop esi
00405006 pop ebx
00405007 pop eax
00405008 ret
00405009 lea esp,[esp]
SUBIt ENDP
>Beware!
Dave.
|
|
|
|
|
Yes, add eax, 0 would reset the carry flag. Weird issue, but fortunately the fix is easy: don't align that loop.
I know, it's common knowledge that loops should be aligned, and that used to help. But these days we have loop buffers and µop caches so it doesn't matter anymore, unless the loop is huge but then the effect is comparatively small.
|
|
|
|
|
Well I'm glad you know what hell he's talking about because none of the rest of us do. I'm just gonna go crawl back into my JavaScript and PHP corner now...
Jeremy Falcon
|
|
|
|
|
Harold,
harold aptroot wrote: so it doesn't matter anymore
I made some timing tests and it took 22% longer to execute an unaligned loop vs an aligned loop, and that was for a short count of loops needed to complete the job, and I had even longer counts I wanted to run.
It does make a difference, align your loops!
Dave.
|
|
|
|
|
Ok, show your tests then, and I'll show you mine, which showed no difference.
I've tested all 16 different alignments using these
global cmp0
proc_frame cmp0
[endprolog]
mov ecx, -10000000
xor eax, eax
jmp _cmp0_loop
align 16
_cmp0_loop:
add ecx, 1
jnz _cmp0_loop
ret
endproc_frame
global cmp15
proc_frame cmp15
[endprolog]
mov ecx, -10000000
xor eax, eax
jmp _cmp15_loop
align 16
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
_cmp15_loop:
add ecx, 1
jnz _cmp15_loop
ret
endproc_frame
Measured over 100 runs, taking the minimum, they all take 10000000 cyles + change (function call overhead and so on). No consistent or significant differences.
|
|
|
|
|
Harold,
Your code is not doing the same thing, it is decrementing a register. My code was propagateing a borrow through multiple DWORDS.
My timing indicated that the aligned code took 3.57 seconds to loop 100,000,000 (one hundred million) times, and 4.36 seconds to loop the same number of times for the unaligned test. That indicates that it took 1.22% longer. In addition, The loop had to re-initialize all of the DWORDS with the correct data for each loop. The loop included this initialization for both the base time and also for the test time, thus the time increment was due to only the time increment for the unaligned loop, meaning that the % difference is really in the neighborhood of 44%.
I will give you the timing differences and the code changes between the two tests. If you want to see the the execution time differences (visual studio "disassembly" tab, then just ask and I will include that also.
RSA-Test TimeSbbLoop - 100M*TEST32: 3.57
;
; Code from Masm 9.0 .lst file for aligned test.
;
C ;*******************************************************************************
C ;
C ; Timing test for alignment.
C ;
C ; esi has the source OFFSET of the data.
C ; edi has the already scaled OFFSET of the destination data.
C ; ecx has the DWORD count to subtract.
C ;
C ;*******************************************************************************
C ALIGN OWORD
00001AEE C .data
C
C ALIGN OWORD
00001AF0 00000020 [ C TestData DWORD 32 DUP (0) ; 128 BYTES, 8 xmm regs
00000000
]
C
00001B70 00000001 C TestDWORD DWORD 1
C
C ALIGN WORD
00001B74 0023 C WORD (LENGTHOF szTestCase - 1)
00001B76 52 53 41 2D 54 C szTestCase BYTE "RSA-Test TimeSbbLoop - 100M*TEST32:",0
65 73 74 20 54
69 6D 65 53 62
62 4C 6F 6F 70
20 2D 20 31 30
30 4D 2A 54 45
53 54 33 32 3A
00
C
000006A0 C .code
C
C ;
C ; Get start time.
C ;
000006A0 C Start:
000006A0 E8 000054BB C CALL GetStartTime
C ; jnz Exit
C ;
C ; Clear the clear regs.
C ;
000006A5 66| 0F EF C0 C pxor xmm0,xmm0
000006A9 66| 0F 6F C8 C movdqa xmm1,xmm0
000006AD 66| 0F 6F D0 C movdqa xmm2,xmm0
000006B1 66| 0F 6F D8 C movdqa xmm3,xmm0
000006B5 66| 0F 6F E0 C movdqa xmm4,xmm0
000006B9 66| 0F 6F E8 C movdqa xmm5,xmm0
000006BD 66| 0F 6F F0 C movdqa xmm6,xmm0
000006C1 66| 0F 6F F8 C movdqa xmm7,xmm0
C ;
C ; Set the loop counter.
C ;
C ; mov edx,1
000006C5 BA 05F5E100 C mov edx,100000000
C
000006CA C OneTest:
000006CA BE 00001AF0 R C mov esi,OFFSET TestData
000006CF 33 C0 C xor eax,eax
000006D1 B9 00000001 C mov ecx,1
000006D6 8B FE C mov edi,esi
000006D8 66| 0F 7F 06 C movdqa [esi + 0],xmm0
000006DC 66| 0F 7F 4E C movdqa [esi + 16],xmm1
10
000006E1 66| 0F 7F 56 C movdqa [esi + 32],xmm2
20
000006E6 66| 0F 7F 5E C movdqa [esi + 48],xmm3
30
000006EB 66| 0F 7F 66 C movdqa [esi + 64],xmm4
40
000006F0 66| 0F 7F 6E C movdqa [esi + 80],xmm5
50
000006F5 66| 0F 7F 76 C movdqa [esi + 96],xmm6
60
000006FA 66| 0F 7F 7E C movdqa [esi + 112],xmm7
70
000006FF BB FFFFFFFF C mov ebx,-1
00000704 89 5E 7F C mov DWORD PTR [esi + 127],ebx
00000707 BE 00001B70 R C mov esi,OFFSET TestDWORD
0000070C EB 02 C jmp DoAll
C
C ALIGN OWORD
C
C ;
C ; Subtract all the value DWORDS.
C ;
00000710 C DoAll:
00000710 8B 1E C mov ebx,[esi]
00000712 8D 76 04 C lea esi,[esi + (SIZEOF DWORD)]
00000715 19 1F C sbb [edi],ebx
00000717 8D 7F 04 C lea edi,[edi + (SIZEOF DWORD)]
0000071A 49 C dec ecx
0000071B 75 F3 C jnz DoAll
0000071D 72 11 C jc Again
0000071F EB 16 C jmp Done
C ;
C ; This is the copy of the code that failed.
C ; The first run will be a baseline where the code is naturally aligned,
C ; then padding instructions will be added to force mis-alignment,
C ; then the test will be run again.
C ;
C ; Pad the code to align "Again" naturally on a mod 16 (OWORD) boundary.
C ; This code is not ever executed - just the above code less the dec ecx.
C ;
00000721 8B 1E C mov ebx,[esi]
00000723 8D 76 04 C lea esi,[esi + (SIZEOF DWORD)]
00000726 19 1F C sbb [edi],ebx
00000728 8D 7F 04 C lea edi,[edi + (SIZEOF DWORD)]
0000072B 49 C dec ecx
0000072C 75 E2 C jnz DoAll
0000072E 72 00 C jc Again
C
C ;ALIGN OWORD
C
C ;
C ; Un-pad the code to un-align.
C ;
C ;
C ; Propogate the borrow.
C ;
00000730 C Again:
00000730 19 07 C sbb [edi],eax
00000732 8D 7F 04 C lea edi,[edi + (SIZEOF DWORD)]
00000735 72 F9 C jc Again
C ;
C ; Done with one test.
C ;
00000737 C Done:
00000737 4A C dec edx
00000738 75 90 C jnz OneTest
C ;
C ; Get the stop time.
C ;
0000073A E8 00005451 C CALL GetStopTime
C ; jnz Exit
C ;
C ; Print the test time.
C ;
C INVOKE WriteNStr,OFFSET szCRLF
0000073F 68 00001956 R * push dword ptr OFFSET FLAT: szCRLF
00000744 E8 00004947 * call WriteNStr
00000749 75 1D C jnz Exit
C
C INVOKE WriteNStr,OFFSET szTestCase
0000074B 68 00001B76 R * push dword ptr OFFSET FLAT: szTestCase
00000750 E8 0000493B * call WriteNStr
00000755 75 11 C jnz Exit
C
00000757 E8 000052F4 C CALL FormatElapsed
C ; jnz Exit
C
C INVOKE WriteNStrCRLF,OFFSET szTOD
0000075C 68 00001AE2 R * push dword ptr OFFSET FLAT: szTOD
00000761 E8 0000495A * call WriteNStrCRLF
00000766 75 00 C jnz Exit
RSA-Test TimeSbbLoop - 100M*TEST32: 4.36
;
; Code from MASM 9.0 .lst file for unaligned test.
;
C ;*******************************************************************************
C ;
C ; Timing test for alignment.
C ;
C ; esi has the source OFFSET of the data.
C ; edi has the already scaled OFFSET of the destination data.
C ; ecx has the DWORD count to subtract.
C ;
C ;*******************************************************************************
C ALIGN OWORD
00001AEE C .data
C
C ALIGN OWORD
00001AF0 00000020 [ C TestData DWORD 32 DUP (0) ; 128 BYTES, 8 xmm regs
00000000
]
C
00001B70 00000001 C TestDWORD DWORD 1
C
C ALIGN WORD
00001B74 0023 C WORD (LENGTHOF szTestCase - 1)
00001B76 52 53 41 2D 54 C szTestCase BYTE "RSA-Test TimeSbbLoop - 100M*TEST32:",0
65 73 74 20 54
69 6D 65 53 62
62 4C 6F 6F 70
20 2D 20 31 30
30 4D 2A 54 45
53 54 33 32 3A
00
C
000006A0 C .code
C
C ;
C ; Get start time.
C ;
000006A0 C Start:
000006A0 E8 000054BB C CALL GetStartTime
C ; jnz Exit
C ;
C ; Clear the clear regs.
C ;
000006A5 66| 0F EF C0 C pxor xmm0,xmm0
000006A9 66| 0F 6F C8 C movdqa xmm1,xmm0
000006AD 66| 0F 6F D0 C movdqa xmm2,xmm0
000006B1 66| 0F 6F D8 C movdqa xmm3,xmm0
000006B5 66| 0F 6F E0 C movdqa xmm4,xmm0
000006B9 66| 0F 6F E8 C movdqa xmm5,xmm0
000006BD 66| 0F 6F F0 C movdqa xmm6,xmm0
000006C1 66| 0F 6F F8 C movdqa xmm7,xmm0
C ;
C ; Set the loop counter.
C ;
C ; mov edx,1
000006C5 BA 05F5E100 C mov edx,100000000
C
000006CA C OneTest:
000006CA BE 00001AF0 R C mov esi,OFFSET TestData
000006CF 33 C0 C xor eax,eax
000006D1 B9 00000001 C mov ecx,1
000006D6 8B FE C mov edi,esi
000006D8 66| 0F 7F 06 C movdqa [esi + 0],xmm0
000006DC 66| 0F 7F 4E C movdqa [esi + 16],xmm1
10
000006E1 66| 0F 7F 56 C movdqa [esi + 32],xmm2
20
000006E6 66| 0F 7F 5E C movdqa [esi + 48],xmm3
30
000006EB 66| 0F 7F 66 C movdqa [esi + 64],xmm4
40
000006F0 66| 0F 7F 6E C movdqa [esi + 80],xmm5
50
000006F5 66| 0F 7F 76 C movdqa [esi + 96],xmm6
60
000006FA 66| 0F 7F 7E C movdqa [esi + 112],xmm7
70
000006FF BB FFFFFFFF C mov ebx,-1
00000704 89 5E 7F C mov DWORD PTR [esi + 127],ebx
00000707 BE 00001B70 R C mov esi,OFFSET TestDWORD
0000070C EB 02 C jmp DoAll
C
C ALIGN OWORD
C
C ;
C ; Subtract all the value DWORDS.
C ;
00000710 C DoAll:
00000710 8B 1E C mov ebx,[esi]
00000712 8D 76 04 C lea esi,[esi + (SIZEOF DWORD)]
00000715 19 1F C sbb [edi],ebx
00000717 8D 7F 04 C lea edi,[edi + (SIZEOF DWORD)]
0000071A 49 C dec ecx
0000071B 75 F3 C jnz DoAll
0000071D 72 0F C jc Again
0000071F EB 14 C jmp Done
C ;
C ; This is the copy of the code that failed.
C ; The first run will be a baseline where the code is naturally aligned,
C ; then padding instructions will be added to force mis-alignment,
C ; then the test will be run again.
C ;
C ; Pad the code to align "Again" naturally on a mod 16 (OWORD) boundary.
C ; This code is not ever executed - just the above code less the dec ecx.
C ;
00000721 8B 1E C mov ebx,[esi]
00000723 8D 76 04 C lea esi,[esi + (SIZEOF DWORD)]
00000726 19 1F C sbb [edi],ebx
00000728 8D 7F 04 C lea edi,[edi + (SIZEOF DWORD)]
0000072B 49 C dec ecx
0000072C 75 E2 C jnz DoAll
C ; jc Again ********************** Remove this pad instruction to un-align.
C
C ;ALIGN OWORD
C
C ;
C ; Un-pad the code to un-align.
C ;
C ;
C ; Propogate the borrow.
C ;
0000072E C Again:
0000072E 19 07 C sbb [edi],eax
00000730 8D 7F 04 C lea edi,[edi + (SIZEOF DWORD)]
00000733 72 F9 C jc Again
C ;
C ; Done with one test.
C ;
00000735 C Done:
00000735 4A C dec edx
00000736 75 92 C jnz OneTest
C ;
C ; Get the stop time.
C ;
00000738 E8 00005453 C CALL GetStopTime
C ; jnz Exit
C ;
C ; Print the test time.
C ;
C INVOKE WriteNStr,OFFSET szCRLF
0000073D 68 00001956 R * push dword ptr OFFSET FLAT: szCRLF
00000742 E8 00004949 * call WriteNStr
00000747 75 1D C jnz Exit
C
C INVOKE WriteNStr,OFFSET szTestCase
00000749 68 00001B76 R * push dword ptr OFFSET FLAT: szTestCase
0000074E E8 0000493D * call WriteNStr
00000753 75 11 C jnz Exit
C
00000755 E8 000052F6 C CALL FormatElapsed
C ; jnz Exit
C
C INVOKE WriteNStrCRLF,OFFSET szTOD
0000075A 68 00001AE2 R * push dword ptr OFFSET FLAT: szTOD
0000075F E8 0000495C * call WriteNStrCRLF
00000764 75 00 C jnz Exit
Dave.
|
|
|
|
|
Of course it's not doing the same thing, it's just testing the effect of alignment by itself.
There is way too much sh*t here to be sure of anything.
|
|
|
|
|
Harold,
My feelings exactly. I will use what I have and beware of any ALIGN in the code section except for the entry at PROC. I will insure that there is no entry to an aligned Label except by a jump or conditional jump.
Dave.
|
|
|
|
|
Isn't the best place to post a Microsoft bug to, Microsoft? You know it will never be fixed thus never closed. Remain there forever
Common sense is admitting there is cause and effect and that you can exert some control over what you understand.
|
|
|
|
|
Just think of the warm-and-fuzzy feeling you will get for submitting it to Microsoft. I know they are still going to look at all those reports I submitted with Windows 95 and thank me later.
My plan is to live forever ... so far so good
|
|
|
|
|
My feeling exactly, I was an ORCAS beta tester.
Dave.
|
|
|
|
|
Companies and government entities all thinking or gone to the cloud, but it gives me an uneasy feeling, perhaps fear of privacy breach, whenever I hear cloud computing.
I can trust the security technology but I just don't trust the people handling my data.
It must be just me.
|
|
|
|
|
Funny, I was just about to grumble about how Toggl is offline. If I were using a local time tracker, this wouldn't be a problem!!!
Leng Vang wrote: It must be just me.
I doubt that.
Marc
|
|
|
|
|
Leng Vang wrote: It must be just me.
Nope.
I can't think of a better way to do things than to hand all your data over to the lowest bidder to look after, to backup, to not steal, and to protect from everybody else.
It's like the world is trying to go back to the "mainframe" model that we worked so hard to get away from when the PC became main-stream...
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
|
|
|
|
|
Remember the network computer?
Same fad new name?
|
|
|
|
|