Смысл введения volatile в языки высокого уровня как раз в том, что компилер обрабатывает проект ПОФАЙЛОВО. Т.е. ему на этапе компиляции файла неизвестно, что кто-то в другом файле меняет некоторую (у Вас глобальную) переменную. Чтобы указать компилеру, что эта переменная меняется не в данном файле, а где то еще (хоть в другом процессе, хоть в другом файле) и введен этот квалификатор. А как же еще дать знать компилятору, что можно оптимизировать, а что нет? Так что все очень просто.
PS. А Линкер просто связывает уже готовые соптимизированные объектные модули. Обратной связи с компилером он не имеет.