So memory segmentation was abandoned in x86-64, but when we use assembly we can specify .code and .data sections/segments in our code, and there is also the stack pointer register.
And the stack segment, data segment and code segment registers.
How and where does that division of code/data/stack happens, is it implemented by the CPU or OS?
Because when we debug and see the disassembly view of some C program, the address space is linear with no divisions.
And when they say that the data segment has "parts" for the globals, statics and the heap, this is OS abstraction?