One pragmatic advantage is that it allows the following very cool snippet;
use_me_like_a_desk = IDesk(instance_of_something_providing_iguest)
You've not had to specify anything there apart from the fact you want something that provides the IDesk interface. As long as you've registered an adapter for converting IGuest to IDesk everything works.
In other words
This is probably the nicest example but there are a number of queries you can make using the registration framework. For example you can essential just ask;
I have this thing, please ensure that it has this interface.
or even in the case of utilities
Please give me the thing that provides this interface for my application
Advantages
Often all the registration of the various adapters and utilities is done per application using zcml. This makes it easy as pie to swap out one adapter for another, or use a different implementation of a utility without having to change a ton of code.
More generally the registration of components reinforces decoupling. You can build multiple modules that work together without having to couple them together. The only things that two modules need to work together is a common set of interfaces.
This makes it incredibly easy to write modules that work seamlessly together without making them dependent on each other, which in turn makes it easy to add, remove, evolve and test new components without massive refactoring.
More information
As I'm sure you've found out the various bits of zope documentation is spread out and difficult to find. It takes a long time I think for some of the concepts and the advantages they bring to click, the best thing you can do is read as much as you can and then go live in a cave for six months in Alaska and meditate on it.
The Comprehensive Guide to Zope Component Architecture is a good start but I also advise reading at least the zope.component docs and the zope.interface docs. In particular this example might help you understand the benefit