Main program and subroutine is a style that is fundamentally focused on functions. When presented with a system to model, you break up the overall functionality of the system into a main program and subroutines.
In the diagram, we can see how subroutines are connected by procedure calls, and may even have nested calls:

The structure of the resulting code is not flat, it’s hierarchical, hence it can be modeled as a directed graph. The subroutines, as declared in the code are structured as a big call tree. As OO languages, procedural programming supports abstract data types, but inheritance is not explicitly supported. It’s not easy to make one abstraction type an extension of another type. Here, the main consideration is the behavior of functions and how data moves through them. As a result, this approach is suitable for computation-focused systems.
Also, it has a principle – one entry, one exit per subroutine. This architectural style promotes modularity and function reuse.
A subroutine may be affected by data changes made by another subroutine. This issue is especially true for global data shared across subroutines. These changes to data can be unpredictable and result in the function receiving an input that is not expected or even not capable of handling correctly (Runtime errors).

Identifying object-oriented components of these kinds of systems can be arduous and result in overly complex solutions, especially when applied to simple programs. That said, depending on the problem, it may be easier to use an object-oriented approach. For example, if abstract data types with inheritance make modeling the problem easier, then it may make more sense to use an object-oriented architectural style.