The Intel 80386, part 4: Arithmetic
Okay, we've laid enough groundwork that we can start looking at instructions. Whereas arithmetic operations on most modern processors are three-operand (two sources and a destination), on the 80386,...
View ArticleThe Intel 80386, part 4: Arithmetic
Okay, we've laid enough groundwork that we can start looking at instructions. Whereas arithmetic operations on most modern processors are three-operand (two sources and a destination), on the 80386,...
View ArticleThe Intel 80386, part 5: Logical operations
The next group of instructions we'll look are the bitwise logical operation. AND r/m, r/m/i ; d &= s, set flags OR r/m, r/m/i ; d |= s, set flags XOR r/m, r/m/i ; d ^= s, set flags TEST r/m, r/m/i...
View ArticleThe Intel 80386, part 6: Data transfer instructions
The most common data transfer operation is the simple copy of a value from one place to another. MOV r/m, r/m/i ; d = s, does not set flags The MOV instruction does not support an 8-bit immediate with...
View ArticleThe Intel 80386, part 7: Conditional instructions and control transfer
Finally we get to use the conditions that we defined way back in Part 2. SETcc r/m8 ; d = 1 if cc is true, d = 0 if false The SETcc family of instructions sets an 8-bit value to 0 or 1 based on a...
View ArticleThe Intel 80386, part 8: Block operations
Most of the special-purpose operations that the 80386 inherited from the 8086 are largely obsolete. Although processors still support them, the implementations are not optimized, and compilers don't...
View ArticleThe Intel 80386, part 9: Stack frame instructions
There are a pair of specialized instructions for creating and tearing down stack frames. ENTER i16, 0 ; push ebp ; mov ebp, esp ; sub esp, (uint16_t)i16 The ENTER instruction sets up a stack frame for...
View ArticleThe Intel 80386, part 10: Atomic operations and memory alignment
Memory access on the 80386 to misaligned locations are supported, although they will operate more slowly than their aligned counterparts. If a memory access straddles a page boundary, an access...
View ArticleThe Intel 80386, part 11: The TEB
The 80386 does not have a lot of registers. But there needs to be a place to record per-thread information. For performance reasons, this should be something available in user mode, to avoid a kernel...
View ArticleThe Intel 80386, part 12: The stuff you don’t need to know
There are quite a few extra instructions that are technically legal in user-mode code, but which you won't see in compiler-generated code because they are simply too weird. PUSHAD ; push all...
View ArticleThe Intel 80386, part 13: Calling conventions
I covered calling conventions for x86 some time ago. Consider that information incorporated by reference. Nonstandard calling conventions are permitted, provided the caller and callee agree what the...
View ArticleThe Intel 80386, part 14: Rescuing a stack trace after the debugger gave up...
So here you go, minding your own business, taking a stack trace, and then the world stops. ChildEBP RetAddr 0019ec98 5654ef4e combase!CoInitializeEx+0x35 0019ecf8 5654e70b...
View ArticleThe Intel 80386, part 15: Common compiler-generated code sequences
The Microsoft compiler employs a few patterns in its code generation that you may want to become familiar with. As we saw earlier, a call to a __thiscall function passes the this pointer in the ecx...
View ArticleThe Intel 80386, part 16: Code walkthrough
Let's put into practice what we've learned so far by walking through a simple function and studying its disassembly. #define _lock_str(s) _lock(s+_STREAM_LOCKS) #define _unlock_str(s)...
View ArticleThe Intel 80386, part 17: Future developments
Although this series focused on the Intel 80386, I did promise to discuss future extensions, so here we go. The Intel 80486 introduced pipelining and on-chip caching. The floating point coprocessor...
View ArticleAccidentally creating a choke point for what was supposed to hand work off...
A customer was investigating performance issues in their program and after much effort was able to identify this function as one source of their problems. // Error checking has been elided for...
View ArticleAccidentally creating a choke point for what was supposed to hand work off...
Last time, we were looking at a function that wanted to kick work off to a background thread but inadvertently ended up blocking the main threads for about as long as the background tasks were...
View ArticleAccidentally creating a choke point for what was supposed to hand work off...
Last time, we identified the reason why a function that intended to queue work to a background thread quickly ended up being a bottleneck because it wanted until the task started running before...
View ArticleHow can I check in Win32 whether a Unicode character is any kind of digit?
Suppose you have a Unicode code unit wchar_t and you want to know whether it represents a numeric digit. If you have the ICU library, you can check if its code point's u_charType is...
View ArticleHow do I convert all these strange Unicode digits into the ones I remember...
Suppose you have a Unicode string and you want to do something mathematical with it. You know how to parse DIGIT ZERO "0" through DIGIT NINE "9" but the string may contain Unicode digits like...
View Article