I'm writing an OS. I use asm! macro to change the code segment.  (Details on 2020/06/08 changes to asm! here and in Rust RFC 2873)
pub unsafe fn set_code_segment(offset_of_cs: u16) {
    asm!("push {0:r}       // 64-bit version of the register
    lea rax, 1f            // or more efficiently, [rip + 1f]
    push rax
    retfq
    1:", in(reg) offset_of_cs);
}
This works. However, if I use push 1f, the address of label 1: will not be pushed. Instead, it will be a memory source operand, loading from [1:]
So the following code
pub unsafe fn set_code_segment(offset_of_cs: u16) {
    asm!("push {0:r}
    push 1f           // loads from 1f, how to push the address instead?
    retfq
    1:", in(reg) offset_of_cs);
}
will not work. Disassembled (by ndisasm) code is this:
11103   │ 0000B9EC  57                push rdi
11104   │ 0000B9ED  FF3425F6B90080    push qword [0xffffffff8000b9f6]
11105   │ 0000B9F4  48CB              retfq
The desired code written in nasm syntax is this:
    [bits 64]
    extern set_code_segment
set_code_segment:
    push rdi
    push change_code_segment         ; absolute address as a 32-bit immediate
    retfq
change_code_segment:
    ret
Linked with the kernel (and extern "C" { pub fn set_code_segment(offset_of_cs: u16) -> () }), the code works. The address of change_code_segment will successfully be pushed.
So my question is: why push 1f of asm! pushes the content of address 1:, not the address of 1:?
 
     
    