Wickets tumbled on the low and slow I S Bindra Stadium pitch as India lost Shikhar Dhawan, who collected his second duck of the game, early after the opener got caught at second slip off an angled Vernon Philander delivery.
In their second innings, India were 13 for one at tea with Murali Vijay (11 batting) and Cheteshwar Pujara (2 batting) at the crease. The hosts have stretched the second innings lead to 30 runs.
Ashwin once again became the leader of the pack, bagging his 13th Test fifer to claim 150 wickets in his 29th match.
Ashwin (5-51), who had sent opener Stiaan van Zyl (5) back in the pavilion on the opening day, got the prized wickets of overnight batsmen Dean Elgar (37) and Hashim Amla (43) and followed it up by scalping Dane Vilas (1) and Imran Tahir (4).
Also Read
Left-arm spinner Ravindra Jadeja also contributed with three wickets while Amit Mishra bagged two, including the all-important scalp of De Villiers.
Though the umpire referred the decision upstairs, it was clear that the ball was legitimate and the catch clean.
The session then saw a 34-run seventh-wicket partnership before Simon Harmer (7) departed, trapped LBW off Mishra. The leg-spinner had another chance of getting a wicket a ball later but failed to take a return catch from new-man Dale Steyn's full-blooded hit.