Gabriel Sechan <[EMAIL PROTECTED]> writes: > I think you'd have a hard time finding someone who truely knew > assembly and Lisp equally well.
And yet, Common Lisp is the only language I know that standardizes the capability to dump the assembly of a function.¹ The language allows staying at a high level, but is willing to expose the low-level outcomes as an aid to optimization. Here's the output of defining four versions of a function that adds 2 to either a list of numbers or just one other number, with the disassembly output following each.² ,----[ Define an binary operator ] | CG-USER(1): (defun add2 (&rest args) | (apply #'+ 2 args)) | ADD2 | CG-USER(2): (disassemble 'add2) | ;; disassembly of #<Function (:ANONYMOUS-LAMBDA 112) @ #x20daae6a> | ;; formals: &REST ARGS | ;; constant vector: | 0: + | | ;; code start: #x20daae04: | 0: 55 pushl ebp | 1: 8b ec movl ebp,esp | 3: 56 pushl esi | 4: 83 ec 34 subl esp,$52 | 7: 89 45 08 movl [ebp+8],eax | 10: 89 55 0c movl [ebp+12],edx | 13: 8b d9 movl ebx,ecx | 15: 80 7f cb 00 cmpb [edi-53],$0 ; SYS::C_INTERRUPT-PENDING | 19: 74 03 jz 24 | 21: ff 57 87 call *[edi-121] ; SYS::TRAP-SIGNAL-HIT | 24: 8b 56 12 movl edx,[esi+18] ; + | 27: 8b 42 f5 movl eax,[edx-11] | 30: c1 e3 02 sall ebx,$2 | 33: 89 5d e4 movl [ebp-28],ebx ; EXCL::LOCAL-0 | 36: 33 d2 xorl edx,edx | 38: b2 08 movb dl,$8 | 40: 83 c4 10 addl esp,$16 | 43: ff 75 e4 pushl [ebp-28] ; EXCL::LOCAL-0 | 46: 6a 00 pushb $0 ; 0 | 48: 52 pushl edx | 49: 50 pushl eax | 50: 33 c9 xorl ecx,ecx | 52: b1 04 movb cl,$4 | 54: ff 97 77 01 call *[edi+375] ; EXCL::APPLYN | 00 00 | 60: c9 leave | 61: 8b 75 fc movl esi,[ebp-4] | 64: c3 ret | 65: 90 nop `---- ,----[ Define an n-ary operator ] | CG-USER(3): (defun add2 (n) | (+ 2 n)) | ADD2 | CG-USER(4): (disassemble 'add2) | ;; disassembly of #<Function (:ANONYMOUS-LAMBDA 114) @ #x20c8022a> | ;; formals: N | | ;; code start: #x20c801cc: | 0: 55 pushl ebp | 1: 8b ec movl ebp,esp | 3: 56 pushl esi | 4: 83 ec 24 subl esp,$36 | 7: 83 f9 01 cmpl ecx,$1 | 10: 74 03 jz 15 | 12: ff 57 8b call *[edi-117] ; SYS::TRAP-WNAERR | 15: 80 7f cb 00 cmpb [edi-53],$0 ; SYS::C_INTERRUPT-PENDING | 19: 74 03 jz 24 | 21: ff 57 87 call *[edi-121] ; SYS::TRAP-SIGNAL-HIT | 24: 8b d0 movl edx,eax | 26: 33 c0 xorl eax,eax | 28: b0 08 movb al,$8 | 30: f6 c2 03 testb dl,$3 | 33: 75 0e jnz 49 | 35: 8b d8 movl ebx,eax | 37: 03 da addl ebx,edx | 39: 70 08 jo 49 | 41: 8b c3 movl eax,ebx | 43: f8 clc | 44: c9 leave | 45: 8b 75 fc movl esi,[ebp-4] | 48: c3 ret | 49: 8b 5f 8f movl ebx,[edi-113] ; EXCL::+_2OP | 52: ff 57 27 call *[edi+39] ; SYS::TRAMP-TWO | 55: eb f3 jmp 44 | 57: 90 nop `---- ,----[ Add optimization declaration ] | CG-USER(5): (defun add2 (&rest args) | (declare (optimize (speed 3) (safety 0))) | (apply #'+ 2 args)) | ADD2 | CG-USER(6): (DISASSEMBLE 'ADD2) | ;; disassembly of #<Function ADD2> | ;; formals: N | | ;; code start: #x20d5e7fc: | 0: 55 pushl ebp | 1: 8b ec movl ebp,esp | 3: 56 pushl esi | 4: 83 ec 24 subl esp,$36 | 7: 8b d0 movl edx,eax | 9: 33 c0 xorl eax,eax | 11: b0 08 movb al,$8 | 13: f6 c2 03 testb dl,$3 | 16: 75 0e jnz 32 | 18: 8b d8 movl ebx,eax | 20: 03 da addl ebx,edx | 22: 70 08 jo 32 | 24: 8b c3 movl eax,ebx | 26: f8 clc | 27: c9 leave | 28: 8b 75 fc movl esi,[ebp-4] | 31: c3 ret | 32: 8b 5f 8f movl ebx,[edi-113] ; EXCL::+_2OP | 35: ff 57 27 call *[edi+39] ; SYS::TRAMP-TWO | 38: eb f3 jmp 27 `---- ,----[ Add type declarations ] | CG-USER(7): (defun add2 (n) | (declare (optimize (speed 3) (safety 0))) | (declare (fixnum n)) | (the fixnum (+ 2 n))) | ADD2 | CG-USER(8): (disassemble 'add2) | ;; disassembly of #<Function (:ANONYMOUS-LAMBDA 119) @ #x20c5b7a2> | ;; formals: N | | ;; code start: #x20c5b774: | 0: 83 c0 08 addl eax,$8 | 3: f8 clc | 4: 8b 75 fc movl esi,[ebp-4] | 7: c3 ret `---- Footnotes: ¹ http://www.lispworks.com/documentation/HyperSpec/Body/f_disass.htm#disassemble ² Using Allegro CL 8.0 on Windows. -- Steven E. Harris -- [email protected] http://www.kernel-panic.org/cgi-bin/mailman/listinfo/kplug-list
