Quick! Can you see the bug in this code?
getTsc PROC NEAR USES EAX EDX
DB 0Fh, 31h
mov WORD PTR es:[ebx][ecx], ax
add ecx, 2
ret
getTsc ENDP
Ok, here's a hint. The following is the actual code generated:
0000006E getTsc PROC NEAR USES EAX EDX
0000006E 0F 31 DB 0Fh, 31h
00000070 50 * push eax
00000071 52 * push edx
00000072 66| 26: 89 04 19 mov WORD PTR es:[ebx][ecx], ax
00000077 83 C1 02 add ecx, 2
ret
0000007A 5A * pop edx
0000007B 58 * pop eax
0000007C C3 * ret 00000h
0000007D getTsc ENDP
If you look closely, you'll see an extra push eax/push edx and an extra pop edx/pop eax inserted by the assembler. Why? Because of the USES EAX EDX on the PROC line. This tells the assembler that EAX and EDX should be preserved, so the assembler adds the PUSH instructions before the first instruction and the POPs before each RET in the function.
So what happened? Well, it turns out that MASM doesn't consider the DB 00Fh/DB 031h as "real" instructions and thus doesn't trigger the generation of the PUSHes. You can validate this by changing the code to:
getTsc PROC NEAR USES EAX EDX
rdtsc
mov WORD PTR es:[ebx][ecx], ax
add ecx, 2
ret
getTsc ENDP
This will get you the following code:
0000006E getTsc PROC NEAR USES EAX EDX
0000006E 50 * push eax
0000006F 52 * push edx
00000070 0F 31 rdtsc
00000072 66| 26: 89 04 19 mov WORD PTR es:[ebx][ecx], ax
00000077 83 C1 02 add ecx, 2
ret
0000007A 5A * pop edx
0000007B 58 * pop eax
0000007C C3 * ret 00000h
0000007D getTsc ENDP
Now it generates correctly. Why? Because RDTSC is an opcode. This kicks MASM's prologue generation code into gear. The worst problem I've seen with this forced me to add a NOP and ORG $-1 in the code, but this was with tool-generated code. Haven't found any Microsoft reports on this behavior, but it's pretty consistent.
This is the first in a series of MASM quirks and bugs. Thanks to Savitha for bringing up this topic.
UPDATE #1: Well, this certainly generated a flurry of e-mails inside of Phoenix. Here's an example of the strange behavior when you put DB's inside of MACROS, sent in by Naonobu:
TEST_MACRO MACRO siidSig
DB 68h ;PUSH imm16
DW siidSig
TEST_MACRO ENDM
testProc PROC USES EAX EDX
TEST_MACRO 1234h
TEST EAX, EAX
RET
testProc ENDP
This code fails for the same reason, which makes it difficult to use macros for new CPU opcodes
Meanwhile, Kelly points out that MASM's default behavior makes it difficult to use PUSHF/POPF because it inserts SUB [R|E]SP, xxxx in the prologue code.Tim



It's happy to find here, I am an BIOS Engineer too, then, I can know what you that is a senior BIOS Engineer care. Unfortunately, some time, we don't care same things, most time I just care silicon featurea more, so could you give me a tip on that, which parts are more importment? what should care in EFI study? How about Linux or other open source system, is it necessary to understand them, which level?
Best Wishes,
One BIOS Engineer.
Posted by: An BIOS Engineer. | September 19, 2007 at 07:03 PM
Hmm!
Can't think of an answer for any of those (as of yet, at least). Maybe if I figure those questions out by myself one day I'll apply :) It's a shame you guys don't have any office in Europe yet, but I guess there's a big market for outsourcing to India and such. Thanks for the reply, nevertheless :)
Posted by: Will anyone read? | April 14, 2007 at 06:57 AM
The list of current jobs is at http://www.phoenix.com/en/About+Phoenix/Employment/Current+Openings/default.htm.
Most of the BIOS today is in assembly language, and the largest collection of x86 assembly gurus are probably found in BIOS companies. I actually started out 20 years ago at Award where I worked as a telemarketer selling typesetting software(!). I had quite a bit of 6502 experience and they needed junior engineers.
Probably the single most important skill is understanding how the machine works. BIOS engineers share a lot of skills with OS driver writers (and many engineers do both). Could you explain how v-tables are implemented for C++? Or how the MTRRs are used to cover odd-sized memory configurations on x86 CPUs? Or the type of problems you would see when reading the status register of a serial device running 4x slower than the system bus?
BIOS engineers are a strange breed. Try explaining what I do at a cocktail party :-)
Posted by: Tim Lewis | April 10, 2007 at 04:47 PM
What kind of credentials and education does one need to be hired by Phoenix? Getting kind of curious...
Assembly is extremely hard to master... I'm at the second year of my CS degree, and I've had a little introduction to it, but not much. What kind of job experiences makes you qualified for BIOS development?
Did you know assembly before starting at Phoenix?
Posted by: Will anyone read? | April 10, 2007 at 03:56 PM