The difference is, that CONS creates a new data structure with
a CAR-attribute (or "slot") and a "CDR"-slot. This is NOT the
processor stack and PUSH does NOT call the corresponding machine
code instruction. CONS can be used to emulate a stack.
Note this on SBCL:
* (defvar *stack* ())
==> *STACK*
* (disassemble #'(lambda (item) (push item *stack*)))
; disassembly for (LAMBDA (ITEM))
; 0AB6252F: 8B0D0025B60A MOV ECX, [#xAB62500] ; '*STACK*
; no-arg-parsing entry point
; 35: 8B4111 MOV EAX, [ECX+17]
; 38: 64 FS-SEGMENT-PREFIX
; 39: 8B00 MOV EAX, [EAX]
; 3B: 83F85A CMP EAX, 90
; 3E: 7503 JNE L0
; 40: 8B41FD MOV EAX, [ECX-3]
; 43: L0: 83F84A CMP EAX, 74
; 46: 742E JEQ L3
; 48: E897E549F6 CALL #x1000AE4 ; ALLOCATE-CONS-TO-ECX
; 4D: 8951FD MOV [ECX-3], EDX
; 50: 894101 MOV [ECX+1], EAX
; 53: 8B150025B60A MOV EDX, [#xAB62500] ; '*STACK*
; 59: 8B4211 MOV EAX, [EDX+17]
; 5C: 64 FS-SEGMENT-PREFIX
; 5D: 83385A CMP DWORD PTR [EAX], 90
; 60: 7405 JEQ L1
; 62: 64 FS-SEGMENT-PREFIX
; 63: 8908 MOV [EAX], ECX
; 65: EB03 JMP L2
; 67: L1: 894AFD MOV [EDX-3], ECX
; 6A: L2: 8BD1 MOV EDX, ECX
; 6C: 8BE5 MOV ESP, EBP
; 6E: F8 CLC
; 6F: 5D POP EBP
; 70: C3 RET
; 71: CC0A BREAK 10 ; error trap
; 73: 02 BYTE #X02
; 74: 18 BYTE #X18 ; INVALID-ARG-COUNT-ERROR
; 75: 4F BYTE #X4F ; ECX
; 76: L3: CC0A BREAK 10 ; error trap
; 78: 02 BYTE #X02
; 79: 1A BYTE #X1A ; UNBOUND-SYMBOL-ERROR
; 7A: 50 BYTE #X50 ; ECX
==> NIL
So there is no machine-PUSH instruction in sbcl when Lisp-PUSH is used.
Norbert