If you have the option to modify the file in which _x
is referenced, you should extract the access to this symbol to a file of its own. First, I will explain how you can do it, and, second, why you should do it.
How to extract it? In the existing file under test, you can replace all accesses to the symbol by calls to access functions. That is, instead of using the value of macro WHAT_EVER
for reading, you call get_what_ever()
. If you use the symbol to modifiy the address, you call set_what_ever(value)
. These getter and setter functions are implemented in a separate file (let's call it, for example, interface_to_assembly.c
). The declarations are put in a header file interface_to_assembly.h
. Now, for your target system, you compile and link the modified file and interface_to_assembly.c
. For your test executable, you create a substitute implementation for interface_to_assembly.c
, maybe interface_to_assembly_double.c
. These substitute implementations could be dummys, stubs, spys, mocks or whatever you need for your tests.
Why is this separation recommendable? First, it removes the tight coupling between the code you want to test from the assembly level, and, potentially, the hardware. Second, it replaces an access to a global variable with a much better controllable function interface. Note, however, that the tiny piece of software in file interface_to_assembly.c
will still not be better testable than before (that is, it will be a candidate for integration testing on the target system). However, for the remaining code (which will likely be the majority), you have much improved testability: Extracting the variable access and replacing it by functions makes it possible to compile the code without any assembly level code. It allows to control every single value access. For example, it becomes possible to create a test setup such that consecutive calls to the getter deliver different values (which is important if you want to simulate concurrent activities of a hardware device).