Subtracting 0x8000 From An Int - Stack Overflow
Có thể bạn quan tâm
-
- Home
- Questions
- Tags
- Users
- Companies
- Labs
- Jobs
- Discussions
- Collectives
-
Communities for your favorite technologies. Explore all Collectives
- Teams
Ask questions, find answers and collaborate at work with Stack Overflow for Teams.
Try Teams for free Explore Teams - Teams
-
Ask questions, find answers and collaborate at work with Stack Overflow for Teams. Explore Teams
Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Learn more about CollectivesTeams
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Learn more about TeamsGet early access and see previews of new features.
Learn more about Labs Subtracting 0x8000 from an int Ask Question Asked 10 years, 10 months ago Modified 10 years, 10 months ago Viewed 3k times 2I am reverse engineering some old C, running under Win95 (yes, in production) appears to have been compiled with a Borland compiler (I don't have the tool chain).
There is a function which does (among other things) something like this:
static void unknown(int *value) { int v = *value; v-=0x8000; *value = v; }I can't quite work out what this does. I assume 'int' in this context is signed 32 bit. I think 0x8000 would be unsigned 32bit int, and outside the range of a signed 32 bit int. (edit - this is wrong, it is outside of a signed 16 bit int)
I am not sure if one of these would be cast first, and how the casting would handle overflows, and/or how the subtraction would handle the over flow.
I could try on a modern system, but I am also unsure if the results would be the same.
Edit for clarity:
1: 'v-=0x8000;' is straight from the original code, this is what makes little sense to me. v is defined as an int.
2: I have the code, this is not from asm.
3: The original code is very, very bad.
Edit: I have the answer! The answer below wasn't quite right, but it got me there (fix up and I'll mark it as the answer).
The data in v is coming from an ambiguous source, which actually seems to be sending unsigned 16 bit data, but it is being stored as a signed int. Latter on in the program all values are converted to floats and normalised to an average 0 point, so actual value doesn't matter, only order. Because we are looking at an unsigned int as a signed one, values over 32767 are incorrectly placed below 0, so this hack leaves the value as signed, but swaps the negative and positive numbers around (not changing order). End results is all numbers have the same order (but different values) as if they were unsigned in the first place.
(...and this is not the worst code example in this program)
Share Improve this question Follow edited Jan 24, 2014 at 0:53 Bruce asked Jan 23, 2014 at 23:49 BruceBruce 231 silver badge4 bronze badges 9- 2 Are you sure the code is correct? Surely it should say *value instead of value. – interjay Commented Jan 23, 2014 at 23:52
- 1 You mentioned reverse engineering. Is the code you wrote in C maybe converted from assembler? In assember SUB doesn't only subtract, but also sets cpu flags that are used in conditional jumps. The word size is probably 16bit, so this could be a check for something. – typ1232 Commented Jan 23, 2014 at 23:55
- > Surely it should say *value instead of value - Yep, sorry typed that up quickly, that part isn't the unknown bit. – Bruce Commented Jan 23, 2014 at 23:56
- This is not converted from asm, I have the original code. It is worth noting that the original code is bad and has many mistakes. – Bruce Commented Jan 23, 2014 at 23:58
- 2 So the code is v=-0x8000 verbatim? Because that's very different from what you've posted in your question. (Your question contains -=, and your last comment contains =-.) – Ken White Commented Jan 24, 2014 at 0:01
2 Answers
Sorted by: Reset to default Highest score (default) Trending (recent votes count more) Date modified (newest first) Date created (oldest first) 3In Borland C 3.x, int and short were the same: 16 bits. long was 32-bits.
A hex literal has the first type in which the value can be represented: int, unsigned int, long int or unsigned long int.
In the case of Borland C, 0x8000 is a decimal value of 32768 and won't fit in an int, but will in an unsigned int. So unsigned int it is.
The statement v -= 0x8000 ; is identical to v = v - 0x8000 ;
On the right-hand side, the int value v is implicitly cast to unsigned int, per the rules, the arithmetic operation is performed, yielding an rval that is an unsigned int. That unsigned int is then, again per the rules, implicitly cast back to the type of the lval.
So, by my estimation, the net effect is to toggle the sign bit — something that could be more easily and clearly done via simple bit-twiddling: *value ^= 0x8000 ;.
Share Improve this answer Follow edited Jan 24, 2014 at 0:51 answered Jan 24, 2014 at 0:20 Nicholas CareyNicholas Carey 73.9k16 gold badges95 silver badges136 bronze badges 5- @PeterGibson. Fixed it for you. Still won't fit in a 16-bit signed int. Clearly, I haven't had enough coffee today :D – Nicholas Carey Commented Jan 24, 2014 at 0:30
- Thanks, drinking my cup now :) Also doesn't this toggle the sign bit rather than clearing it? – Peter Gibson Commented Jan 24, 2014 at 0:31
- So the negative on 0x8000 has no effect? I suspect this but can't be sure. If v is negative this results in a inverted positive (-1=>32767, -32768->0) number (as you describe, clearing the sign bit). If it is positive in the first place doesn't it do the reverse (make negative and invert). – Bruce Commented Jan 24, 2014 at 0:38
- I just tested it in Visual C. Coercing things to short and unsigned short. It does indeed appear toggle the sign bit. Answer amended. – Nicholas Carey Commented Jan 24, 2014 at 0:53
- @PeterGibson Note: 0x8000 is an unsigned with a value of 32,768. 32768 is a long with same value. – chux Commented Sep 23, 2016 at 19:21
There is possibly a clue on this page http://www.ousob.com/ng/borcpp/nga0e24.php - Guide to Borland C++ 2.x ( with Turbo C )
There is no such thing as a negative numeric constant. If a minus sign precedes a numeric constant it is treated as the unary minus operator, which, along with the constant, constitutes a numeric expression. This is important with -32768, which, while it can be represented as an int, actually has type long int, since 32768 has type long. To get the desired result, you could use (int) -32768, 0x8000, or 0177777.
This implies the use of two's complement for negative numbers. Interestingly, the two's complement of 0x8000 is 0x8000 itself (as the value +32768 does not fit in the range for signed 2 byte ints).
So what does this mean for your function? Bit wise, this has the effect of toggling the sign bit, here are some examples:
f(0) = f(0x0000) = 0x8000 = -32768 f(1) = f(0x0001) = 0x8001 = -32767 f(0x8000) = 0 f(0x7fff) = 0xffffIt seems like this could be represented as val ^= 0x8000, but perhaps the XOR operator was not implemented in Borland back then?
Share Improve this answer Follow edited Jan 24, 2014 at 0:53 answered Jan 24, 2014 at 0:02 Peter GibsonPeter Gibson 19.5k7 gold badges62 silver badges64 bronze badges 4- That would make sense. 0x8000 is 32768 in decimal. And 0177777 (octal) is 65535 in decimal. – user1508519 Commented Jan 24, 2014 at 0:06
- This really helps, but I am still not sure what the end result is to the int. – Bruce Commented Jan 24, 2014 at 0:17
- Thanks this is correct, I just saw Nicholas Carey's edit first. – Bruce Commented Jan 24, 2014 at 1:11
- The XOR operator was implemented in Borland back then. – chux Commented Sep 23, 2016 at 19:46
Your Answer
Reminder: Answers generated by artificial intelligence tools are not allowed on Stack Overflow. Learn more
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Draft saved Draft discardedSign up or log in
Sign up using Google Sign up using Email and Password SubmitPost as a guest
Name EmailRequired, but never shown
Post Your Answer DiscardBy clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.
Not the answer you're looking for? Browse other questions tagged
or ask your own question.- The Overflow Blog
- Your docs are your infrastructure
- Featured on Meta
- More network sites to see advertising test [updated with phase 2]
- We’re (finally!) going to the cloud!
- Call for testers for an early access release of a Stack Overflow extension...
Related
7 Subtracting two numbers without using '-' operator 4 Subtracting Decimal Values (Assembly) 3 int $0x80 in Programming From The Ground Up 1 subtracting two unsigned 32-bit integers and assign to 64-bit signed integer 0 Decrement unsigned integer by 1 0 Subtraction with ReadInt 0 Adding 0 at starting of int value in c 0 Subtraction over ranges of bits 1 Subtracting 1 from 0 in 8 bit binary 1 Subtracting digits from an integer right to leftHot Network Questions
- Polynomial.java - a Java class for dealing with polynomials with BigDecimal coefficients
- Why is Anarchism not considered fundamentally against the "democratic order" in Germany?
- Why did the angel strain or dislocate Yaakov's hip-socket?
- Identifying a TNG episode where Dr. Pulaski instructs another doctor on a sling
- Is there a symbol for the Hyper key?
- Will a laptop battery that stays connected to its charger be damaged?
- How do I go about rebranding a fully deleted project that used to have a GNU General Public License v3.0 but is now fully inaccessible
- Static vs dynamic certificate pinning
- Can you please advise on kerning?
- Is there a cryptographic method that can only decrypt for a certain range of seeds?
- How much ebikes actually benefit from ebike specific wheels, tires, and forks?
- How to say "Each one of the following" in German?
- Shell Script to Normalize the data
- Table structure with multiple foreign keys and values
- Schrödinger's cat ++
- Being honest with rejection vs. preparing applicant for future possibility
- How can I politely decline a request to join my project by a free rider professor
- What's a good way to append a nonce to ciphertext in Python for AES GCM in Python?
- Do market-makers often act as a taker in other markets or assets while hedging?
- What is this insect found in an apartment in Brazil?
- If someone’s words are likely to be disregarded, how to describe the quality of “meaning” they lack?
- Sorites paradox and emergence
- In GR, what is Gravity? A force or curvature of spacetime?
- Clarification and Proof of Inequality (8.11) in Analytic Number Theory by Iwaniec and Kowalski
To subscribe to this RSS feed, copy and paste this URL into your RSS reader.
lang-cTừ khóa » C 0x8000
-
Does 0<(unsigned Short)0x8000 Hold? | C Programming
-
You May Receive Error Code 0x80004005 Or Other Error Codes When ...
-
Problem Accessing Memory Above 0x8000
-
Bitwise And - C Board
-
Whether 0x8000 Is Voilating MISRA C-2012 Rule 7.2 ?
-
Understand Configuration Register Usage On All Routers - Cisco
-
Thread: What Does #define IP_RF 0x8000 Mean? - CodeGuru Forums
-
How To Fix Error Code 0x80004005 - Lifewire
-
SOLVED: How To Fix Error 0x80004005
-
Error 0x80070002 Occurs While Launching Or Installing A PC Game
-
[PDF] Code From 3c59x.c