Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

MCode access violation on: long long >> arg


  • Please log in to reply
4 replies to this topic
infogulch
  • Moderators
  • 717 posts
  • Last active: Jul 31 2014 08:27 PM
  • Joined: 27 Mar 2008
Ok, after hours of trying to isolate this issue I've pared it down to this, which gives an access violation (0xC0000005, from DllCall docs)

(C, x86)
int f(int s) { return 9001LL >> s; }

Requirements to reproduce the runtime error:[*:2xqhdyc1]The left operand MUST be type long long, signed or unsigned, param or literal value. (Other integer types work fine)
[*:2xqhdyc1]The right operand MUST be an arg (not a literal value), OR another variable derived from the arg, of any integer type.
What is going on here?

This is the resultant .cod file:
; Listing generated by Microsoft (R) Optimizing Compiler Version 16.00.30319.01 

	TITLE	C:\Users\Joe\AppData\Local\Temp\code.c
	.686P
	.XMM
	include listing.inc
	.model	flat

INCLUDELIB LIBCMT
INCLUDELIB OLDNAMES

PUBLIC	_f
EXTRN	__allshr:PROC
; Function compile flags: /Ogtpy
;	COMDAT _f
_TEXT	SEGMENT
_s$ = 8							; size = 4
_f	PROC						; COMDAT
; File c:\users\joe\appdata\local\temp\code.c
; Line 2
  00000	8b 4c 24 04	 mov	 ecx, DWORD PTR _s$[esp-4]
  00004	b8 29 23 00 00	 mov	 eax, 9001		; 00002329H
  00009	33 d2		 xor	 edx, edx
  0000b	e9 00 00 00 00	 jmp	 __allshr
_f	ENDP
_TEXT	ENDS
END

This is the ahk code I'm using to run it: (basic & L, haven't tried v2 alpha)
MCode(f, "8B4C2404B82923000033D2E900000000")

msgbox % DllCall(&f, "int", 2, "CDecl") "`n" ErrorLevel

MCode(ByRef var, hex) {
    VarSetCapacity(var, StrLen(hex)//2)
    loop % StrLen(hex)//2
        NumPut("0x" SubStr(hex, A_Index*2-1, 2), var, A_Index-1, "UChar")
}


Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006
0000b   e9 00 00 00 00    jmp    __allshr
This jump goes nowhere - it may as well not be there at all, which also means there's no determinate end to the function. Normally the zeros would be replaced with the offset of the __allshr function, which is not shown in your code listing. Basically, the problem is that the 32-bit compiler has to generate additional functions for performing 64-bit math. I suppose you could work around it by splitting the number up and using 32-bit math, or by finding a code listing of __allshr and inlining it into your code.

infogulch
  • Moderators
  • 717 posts
  • Last active: Jul 31 2014 08:27 PM
  • Joined: 27 Mar 2008
Oh I see... interesting that both __allshr isn't automatically inlined/included and also that it needs a software function to perform shift right on 64 bit integers. I thought that line looked a little weird, though I didn't know how to read assembly.

Oh well, I'll just use 32 bit integers if 64 bit integers are going to give me trouble. :p

Thanks Lexikos :)

Drugwash
  • Members
  • 1078 posts
  • Last active: May 24 2016 04:20 PM
  • Joined: 07 Sep 2008
Could this be related to the issue presented on Larry Osterman's blog here? :roll:

(AHK 1.0.48.05 and Win98SE) forever | My scripts are here


Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006
No. That's comparing 32-bit code which uses __allshr to 64-bit code which uses the sar instruction with a 64-bit register. In that case, the 64-bit code is what has the problem, and that only when shifting by >= 64.

I suppose it needs __allshr because there is no 64-bit "shift right" instruction in the 32-bit x86 instruction set.