TweetFollow Us on Twitter

June 95 - KON & BAL'S PUZZLE PAGE

KON & BAL'S PUZZLE PAGE

A Branch Too Far

Chris YERGA

[IMAGE 124-129_Puzzle_Page_http1.GIF]

See if you can solve this programming puzzle, presented in the form of a dialog between Konstantin Othmer and guest puzzler Chris Yerga. The dialog gives clues to help you. Keep guessing until you're done; your score is the number to the left of the clue that gave you the correct answer. Even if you never run into the particular problems being solved here, you'll learn some valuable debugging techniques that will help you solve your own programming conundrums. And please, make KON & BAL's day by submitting a puzzle of your own to AppleLink DEVELOP.

Chris I have a piece of code that runs fine on my Quadra, but when I run it on a plain old 68000 it crashes.

KON A 68000? So you're still trying to get GX to run on that Mac Portable in Cary's office, huh? How does it crash?

Chris With an address error.

KON What's hard about that? Your code is doing a 2- or 4-byte access to an odd address, which is OK on a 68040 but not on a 68000. It's a trivial problem.

Chris That's what I thought, but the address it's accessing appears to be uninitialized data. The code is simply allocating a block and then storing a pointer in the block, but the store never seems to occur, because afterward the block has random data in it. And of course the block itself is long-aligned, because it came from the Memory Manager, so there's no problem there.

KON Maybe on your Quadra, but on a Mac Plus the Memory Manager allocates blocks that are word-aligned.

Chris Thanks for the history lesson, chief, but this isn't a Mac Plus and the Memory Manager on this machine is much different -- much simpler, actually. It just so happens that our Memory Manager always long-aligns blocks.

KON Since when are you writing new Memory Managers? I thought you wrote graphics code.

Chris Yes. But the cornerstone of any decent graphics system is its Memory Manager -- I wouldn't expect a "QuickDraw classic" guy like you to understand.

KON I understand memory management just fine, Jackson. Show me where you're setting up this data.

100 Chris This is the interesting section:

NewDMAQueueEntry
...
+0030 0020C5D6  MOVE.L  D3,D0
+0036 0020C5DC  _NewPtr
+0038 0020C5DE  MOVE.L  A0,-$0008(A6)
+003C 0020C5E2  MOVE.L  -$000C(A6),-(A7)
+0040 0020C5E6  MOVEA.W -$000E(A6),A1
+0044 0020C5EA  MOVE.L  A1,-(A7)
+0046 0020C5EC  JSR     *+$53A4 ; 00211990
+004A 0020C5F0  MOVE.L  D0,-$000C(A6)
+004E 0020C5F4  MOVE.L  A2,(A0,D0.L)

It makes the _NewPtr call, makes some other function call, and then stores the pointer in A2 into our newly allocated buffer.

KON What's the other function call doing?

95 Chris I'm not sure, actually. The C source doesn't indicate that a function call should be happening:

buffer = NewPtr(totalSize);
count = count * size;
*(long *) (buffer + count) = (long) handlerProc;

The only thing I see happening in the source code is a multiply. You don't need a function call for that.

KON Could this be some wacky C++ operator overloading nonsense? C++ is very good at generating extra function calls. I think we'd better bring a SmartFriend in on this one.

Chris Don't bring out the big guns just yet. The code is written completely in plain old C: no C++ and no CFront.

KON It's got to be code you've written, because it's a PC-relative JSR. Since it's not an A5- relative JSR, it's not going through the jump table, so it couldn't have been linked in from a library or something external to your program. It looks like a call to a static function.

Chris Actually, all the JSR instructions in this code are PC-relative. I wrote a tool that transforms all JSRs that go through the jump table to PC-relative JSRs. You may want to sit down for this next part -- it's a little tricky.

KON That's why it ended up in the Puzzle Page. Let's hear it.

90 Chris All the code is being built into a ROM; however, our development system of choice only allows us to build our code as a Mac application. So I created a custom tool that postprocesses the application and turns it into something that will run out of ROM. Basically we use the CODE 0 jump table to link everything together.

KON I see. You know where the code will reside in ROM, so you fake out the jump table to make it look as if all the segments are loaded. Since nothing will ever move or unload, your ROM jump table entries never need to change. Pretty tricky.

Chris But not tricky enough. The scheme you describe will work, but it has two problems. First, our ROM can be mapped into different addresses, so the code must be completely relocatable. A Mac jump table contains JMP instructions with fixed long addresses (for example, JMP $4083143A), which are not relocatable. Second, as a cycle counter like you should know, the jump table is superfluous here, because no code will ever move or unload while it's running. You're doing a JSR to the JMP in the jump table -- the extra JMP is unnecessary and wastes cycles.

KON I didn't know you GX guys counted cycles. How do you get away with removing the extra JMP?

85 Chris Our tool scans all the object code for all instructions that reference the jump table. They are JSR xx(A5) (function call), PEA xx(A5) (pass a function pointer on the stack), and LEA xx(A5),Ax (get a function pointer in a local variable). When it finds one of these instructions, it looks up the function in the jump table and changes the instruction to a PC-relative version that simply references the address of the target function directly. Everything is PC-relative, so it relocates correctly, and there are no extra instructions.

KON But the PC-relative addressing mode has only a 16-bit offset, so you can only reference functions within 32K of the PC. Is your ROM that small?

80 Chris Are you kidding? The pictures for the About box are bigger than that. When we need to reference a function that's beyond 32K, we create a "jump island" that's still PC- relative but allows us a greater reach.

0020122A:   JSR     $00201FA8       ;go to jump island
0020122E:   MOVE.W  D0,(A3)
...
00201FA8:   LEA     *+0,A0          ;get pc
00201FAC:   ADDA.L  #$00014B02,A0   ;add long offset
00201FB2:   JMP (A0)                ;jump to destination

KON That looks suspicious to me. You're messing with A0 in your jump island.

75 Chris But that should be OK because the whole thing is written in C, which never passes a parameter in A0 and never expects A0 to be preserved.

KON I can't find a specific problem, but I'm still a little suspicious of all this OS code you're writing. You said that this code runs fine on your Quadra. Does the Quadra version undergo the jump table transformation process?

Chris No. The Quadra version is run just like a Mac application out of RAM.

KON Tell me all the differences between the two environments.

70 Chris The 68000 version of the software is different in two ways. First, it's generated with the exact same compiler, but without 68020 code generation enabled. Then, I run it through my BuildROM tool, which transforms all the jump table references to PC- relative references. The 68000 target hardware is a diskless system; the only way to get code into it is through ROM cartridges, so we can't try to run a version of the software that hasn't undergone the BuildROM step.

KON So the bug may have nothing to do with the differences between the 68040 and 68000 processors -- it may be the BuildROM process. Let's sum up what we know: First we saw a piece of code that allocates a block of memory and stores a value into that block, but the store never seems to happen. Near that code is an unexplained JSR which we believe is a function call. Finally, we know that a critical difference in the environment is that you alter the code path of function calls. It's really starting to smell like your BuildROM tool.

Chris The evidence is all circumstantial, counselor. The only questionable part of the BuildROM process we've seen is my usage of A0 in the jump islands, but I can't see a case where a C function call takes a parameter in A0 or assumes A0 is preserved.

KON We should trace through the NewDMAQueueEntry routine and see what that mysterious function call is doing.

65 Chris I put in a breakpoint. But when I run the program again, I drop into the debugger with a debug message complaining that some kind of parameter is out of range.

KON You mean the bug isn't reproducible?

Chris After many tries, this is the first time it's failed this way.

KON Hmm. What parameter is out of range?

Chris The debug message doesn't say, exactly. The value it's complaining about is in D2. The value is $00004E56.

KON That's a funny-looking number. It looks like an opcode to me. dh 4E56 tells me it's a LINK A6,#xx instruction. Where did the value in D2 come from?

60 Chris From a MOVE.W (A0),D2 instruction. The code seems to think A0 points to some data.

KON But it looks as if it points to code instead. Where is A0?

Chris It points to the start of a routine called VBLHandler.

KON VBLHandler sure sounds like an interrupt service routine to me, which would explain the various failure modes. Is the routine written in C? C routines don't bother to preserve A0, so your interrupt routine is trashing a register!

55 Chris There's some inline assembly code to save all the registers. Take a look:

 void VBLHandler(void)
{
asm {
    MOVEM.L     A0-A6/D0-D7, -(SP)
};

FlushQueue();
HandleVBLTasks();

asm {
    MOVEM.L     (SP)+, A0-A6/D0-D7
};
}

KON It seems quite suspicious to me that A0 points to the beginning of this routine. Sounds like your jump islands are at work. Look at the interrupt vector for your VBL handler.

50 Chris On this particular machine the VBL is handled as a level-6 interrupt. The level-6 vector is at $0078. It points to a jump island entry like the one above.

KON And the first thing it does is trash A0 before your inline assembly gets a chance to save it! Maybe you should stick to drawing bitmaps and leave the OS work to someone else.

45 Chris The problem is that the code that installed the interrupt handler is more than 32K away from the handler itself. So when it did an LEA xx(A5),Ax to get the address of the interrupt handler, the ROM builder tool needed to stick a jump island in there. Nasty. But I still need a way to do PC-relative jump islands.

KON Use the stack, son. Try this:

PEA     * ;push the pc
ADD.L   #xxxxxx,(sp) ;add a long offset
RTS     ;jump to the destination

Chris All this and you can draw bitmaps too! I'll fix the ROM builder tool to do this. But somehow I doubt that a VBL interrupt was hitting us at the same spot in my NewDMAQueueEntry routine every time. There must be another problem there.

KON We still have the breakpoint there; before we recompile and fix the bug, let's run it again and see if we can get the original failure mode to happen again.

40 Chris This time we hit the breakpoint. We trace over the NewPtr and see that it returns a valid pointer in A0. We step into the JSR at $20C5EC and it takes us to one of my jump islands.

KON Which alters A0, and then jumps to the function being called. What is the function doing?

35 Chris It's a very short routine; it just takes some parameters off the stack and does a few multiplies. It returns the result in D0 just like any normal C function would.

KON But is it using the trashed A0 for anything?

Chris No. In fact, it's not using any address registers at all. It only uses data registers for the multiplies. I repeat: no C function would ever take a parameter in A0.

KON So we return to the NewDMAQueueEntry routine, with a return value in D0. We save D0 in a local variable on the stack frame, and then hit the instruction at $20C5F4, which stores a value in the buffer pointed to by A0.

30 Chris But A0 still has the result of the jump island calculation in it. The code didn't set up A0 to point to anything!

KON Look at the listing of NewDMAQueueEntry again. The code gets the result of the NewPtr call in A0, makes the function call, and then assumes that A0 still has the valid pointer in it. But meanwhile, some wannabe OS programmer has gotten in there and hosed A0 on us!

20 Chris That function call seems to be doing the multiply. It must be some runtime math library that the compiler uses.

KON I'll bet one of your variables is a long word. With 68020 code generation turned on, the compiler was able to generate a long multiply instruction, but the 68000 doesn't have a long multiply instruction, so it calls the math library.

10 Chris I see. Since the math library was written by the same people who wrote the compiler, their code generator knows that A0 won't get trashed, so it doesn't bother to save and restore it around the call to the long multiply routine. Pretty sneaky.

KON But nice. You want the person writing your code generator to be the ultimate cycle counter. Since the Mac Segment Loader implementation doesn't trash A0, it's a worthwhile optimization for them to make.

Chris Except in this case, the code that performs a multiply is more than 32K away from where the math library resides in the ROM, so it hits a jump island and loses the value of A0.

KON Even a lowly register like A0 is sacred sometimes.

Chris So it appears.

KON Nasty.

Chris Yeah.

SCORING

  • 80-100 Please fax your resumé to Catapult Entertainment, Inc., (408)366-2471.
  • 60-75 We also have junior positions available.
  • 40-55 Don't worry; just let CopyBits do the tricky stuff.
  • 10-35 I see you've done your share of long multiplies. *

Chris YERGA During his four years working on QuickDraw GX, Chris learned a lot about graphics systems and large projects. He's currently employed by Catapult Entertainment, where he learned that a Sega is kinda like a Macintosh, a SNES is kinda like an Apple II GS, and carbon dioxide can be explosive. *

Thanks to Josh Horwich,

KON (Konstantin Othmer), and BAL (Bruce Leak) for reviewing this column. *

 
AAPL
$99.26
Apple Inc.
+0.08
MSFT
$45.90
Microsoft Corpora
+0.00
GOOG
$569.90
Google Inc.
+1.63

MacTech Search:
Community Search:

Software Updates via MacUpdate

Cocktail Family License (5 Macs) 7.6.1 -...
Cocktail is a general purpose utility for OS X that lets you clean, repair and optimize your Mac. It is a powerful digital toolset that helps hundreds of thousands of Mac users around the world get... Read more
Cocktail 8.0 Beta 2 - General maintenanc...
Cocktail is a general purpose utility for OS X that lets you clean, repair and optimize your Mac. It is a powerful digital toolset that helps hundreds of thousands of Mac users around the world get... Read more
QuickBooks 2015 16.0.0.1352 R1 - Financi...
QuickBooks 2015 helps you manage your business easily and efficiently. Organize your finances all in one place, track money going in and out of your business, and spot areas where you can save.... Read more
Mac DVDRipper Pro 5.0.1 - Copy, backup,...
Mac DVDRipper Pro is the DVD backup solution that lets you protect your DVDs from scratches, save your batteries by reading your movies from your hard disk, manage your collection with just a few... Read more
Apple OS X bash Update 1.0 - Fix for sec...
The OS X bash Update fixes a security flaw in the bash UNIX shell on OS X 10.9.5 (also on OS X 10.8 and 10.7 [see Related Links below]). OS X 10.9.5 or later Downloads for OS X 10.8 and OS X 10.7 in... Read more
SyncTwoFolders 2.0.5 - Syncs two user-sp...
SyncTwoFolders simply synchronizes two folders. It supports synchronization across mounted network drives and it is a possibility to run a simulation showing in a log what will be done. Please visit... Read more
FinderPop 2.5.7 - Classic Mac utility, n...
FinderPop is a Universal preference pane that extends OS X's contextual menus using a FinderPop Items folder much as the Apple Menu Items folder used to do for the Apple menu. It has other features... Read more
VueScan 9.4.45 - Scanner software with a...
VueScan is a scanning program that works with most high-quality flatbed and film scanners to produce scans that have excellent color fidelity and color balance. VueScan is easy to use, and has... Read more
LibreOffice 4.3.2.2 - Free Open Source o...
LibreOffice is an office suite (word processor, spreadsheet, presentations, drawing tool) compatible with other major office suites. The Document Foundation is coordinating development and... Read more
calibre 2.4 - Complete e-library managem...
Calibre is a complete e-book library manager. Organize your collection, convert your books to multiple formats, and sync with all of your devices. Let Calibre be your multi-tasking digital... Read more

Latest Forum Discussions

See All

The Maze Runner Review
The Maze Runner Review By Lee Hamlet on October 2nd, 2014 Our Rating: :: A NICE CHANGE OF PACEUniversal App - Designed for iPhone and iPad The Maze Runner is a surprisingly enjoyable movie tie-in that will succeed in keeping... | Read more »
RPG Soul of Deva (Games)
RPG Soul of Deva 1.0.0 Device: iOS Universal Category: Games Price: $3.99, Version: 1.0.0 (iTunes) Description: SPECIAL PRICE56% OFF(USD 8.99 -> USD 3.99)!!! Demons attack humans, and humans live in fear of them...Set off on a... | Read more »
Banner Saga (Games)
Banner Saga 1.0.17 Device: iOS Universal Category: Games Price: $9.99, Version: 1.0.17 (iTunes) Description: NOTE: The Banner Saga does NOT run on iPhone 4. iPhone 4S and more modern devices recommended. | Read more »
Beatbuddy HD (Games)
Beatbuddy HD 1.0.2 Device: iOS Universal Category: Games Price: $4.99, Version: 1.0.2 (iTunes) Description: **IMPORTANT** Beatbuddy runs only on iPhone 6, 6 Plus, 5, 5c, 5s, iPad 4, iPad Mini Retina and iPad Air. | Read more »
Spirits of Spring (Games)
Spirits of Spring 1.0.1 Device: iOS Universal Category: Games Price: $4.99, Version: 1.0.1 (iTunes) Description: From the creators of the award-winning empathy game, Papo & Yo, comes a tale about finding strength. | Read more »
I am a brave knight (Games)
I am a brave knight 1.0 Device: iOS Universal Category: Games Price: $.99, Version: 1.0 (iTunes) Description: Do you have ten minutes to live a life? | Read more »
iKeywi - Customizable 5-Row Keyboard (U...
iKeywi - Customizable 5-Row Keyboard 1.0 Device: iOS Universal Category: Utilities Price: $.99, Version: 1.0 (iTunes) Description: Want to add an extra row to your iPhone/iPad? One of the most popular keyboard extension in iOS... | Read more »
Manage Your Cloud – Wunderlist Now Suppo...
Manage Your Cloud – Wunderlist Now Supports Dropbox Posted by Jessica Fisher on October 1st, 2014 [ permalink ] Universal App - Designed for iPhone and iPad | Read more »
Nexticy Review
Nexticy Review By Jennifer Allen on October 1st, 2014 Our Rating: :: IDEAL FORM CREATIONiPad Only App - Designed for the iPad Nexticy allows you to make your own forms for research purposes or to organize your business better. It’s... | Read more »
Tiny Troopers: Alliance Marches onto the...
Tiny Troopers: Alliance Marches onto the App Store Tomorrow Posted by Jessica Fisher on October 1st, 2014 [ permalink ] Tiny Troopers: Alliance, by Kukouri, is a | Read more »

Price Scanner via MacPrices.net

Apple drops prices on refurbished 27-inch iMa...
The Apple Store has dropped prices on Apple Certified Refurbished 27″ iMacs, now available for up to $340 off the cost of new models. Apple’s one-year warranty is standard, and shipping is free: - 27... Read more
Logitech Type+ iPad Air Keyboard Case: Laptop...
If you want to make your iPad Air look and feel more like a laptop for productivity use, as well as protect it from impacts, spills, and scratches while on the move, the new Logitech Type+, a... Read more
ASUS, Lenovo, and Amazon Slug It Out For Tabl...
According to market intelligence firm ABI Research, Apple and Samsung have led the touchscreen tablet market by a substantial margin since Apple energized the category back in 2010. However, ABI says... Read more
Branded Tablet Growth Expected to Disappoint...
ABI Research says the 200 million annual shipments milestone for branded tablets continues to elude OEM vendors, and overall growth for 2014 is set to come in at a disappointing 2.5 percent. Apple... Read more
Amazon offers 13-inch MacBook Air for $899, $...
Amazon.com has the 13″ 1.4GHz 128GB MacBook Air on sale for $100 off MSRP including free shipping: - 13″ 1.4GHz 128GB MacBook Air: $899.99 Read more
Apple resting On Its iPhone Laurels? – The ‘B...
Apple calls its new iPhone 6 and 6 Plus “The Biggest Advancements in iPhone History,” but does reality live up to the hype? “Seldom have so many waited so breathlessly for so little,” tweeted veteran... Read more
Roundup of Apple Mac and iPad Education disco...
Purchase a new Mac or iPad at The Apple Store for Education and take up to $300 off MSRP. All teachers, students, and staff of any educational institution qualify for the discount. Shipping is free,... Read more
Apple Boycotts German Magazine Computer Bild...
Apple has revoked its PR accreditation of Germany’s Computer Bild, Europe’s best-selling PC magazine, in reaction to Bild’s posting of a “#Bentgate” YouTube video. Axel Telzerow, editor in chief of... Read more
iPhone 6 & iPhone 6 Plus Available in Chi...
Apple has announced that iPhone 6 and iPhone 6 Plus will be available in China beginning Friday, October 17 from the Apple Online Store (http://www.apple.com), Apple’s retail stores, and an expansive... Read more
MacBook Airs on sale for $100 off MSRP, start...
Best Buy has the new 2014 MacBook Airs on sale for $100 off MSRP on their online store. Choose free home shipping or free local store pickup (if available). Prices valid for online orders only, in-... Read more

Jobs Board

*Apple* Retail - Multiple Positions (US) - A...
Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, you're also the Read more
*Apple* Retail - Multiple Positions (US) - A...
Job Description: Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, Read more
Senior Event Manager, *Apple* Retail Market...
…This senior level position is responsible for leading and imagining the Apple Retail Team's global event strategy. Delivering an overarching brand story; in-store, Read more
*Apple* Solutions Consultant (ASC) - Apple (...
**Job Summary** The ASC is an Apple employee who serves as an Apple brand ambassador and influencer in a Reseller's store. The ASC's role is to grow Apple Read more
Project Manager / Business Analyst, WW *Appl...
…a senior project manager / business analyst to work within our Worldwide Apple Fulfillment Operations and the Business Process Re-engineering team. This role will work Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.