x86 - What does cltq do in assembly? -
0x0000000000400553 <main+59>: mov -0x4(%rbp),%eax 0x0000000000400556 <main+62>: cltq 0x0000000000400558 <main+64>: shl $0x3,%rax 0x000000000040055c <main+68>: mov %rax,%rdx
in fact programe simple :
5 int main(int argc, char *argv[]) { 6 int = 0; 7 while(environ[i]) { 8 printf("%s\n", environ[i++]); 9 } 10 return 0;
but assembly output pretty long:
dump of assembler code function main: 0x0000000000400518 <main+0>: push %rbp 0x0000000000400519 <main+1>: mov %rsp,%rbp 0x000000000040051c <main+4>: sub $0x20,%rsp 0x0000000000400520 <main+8>: mov %edi,-0x14(%rbp) 0x0000000000400523 <main+11>: mov %rsi,-0x20(%rbp) 0x0000000000400527 <main+15>: movl $0x0,-0x4(%rbp) 0x000000000040052e <main+22>: jmp 0x400553 <main+59> 0x0000000000400530 <main+24>: mov -0x4(%rbp),%eax 0x0000000000400533 <main+27>: cltq 0x0000000000400535 <main+29>: shl $0x3,%rax 0x0000000000400539 <main+33>: mov %rax,%rdx 0x000000000040053c <main+36>: mov 0x2003e5(%rip),%rax # 0x600928 <environ@@glibc_2.2.5> 0x0000000000400543 <main+43>: lea (%rdx,%rax,1),%rax 0x0000000000400547 <main+47>: mov (%rax),%rdi 0x000000000040054a <main+50>: addl $0x1,-0x4(%rbp) 0x000000000040054e <main+54>: callq 0x400418 <puts@plt> 0x0000000000400553 <main+59>: mov -0x4(%rbp),%eax 0x0000000000400556 <main+62>: cltq 0x0000000000400558 <main+64>: shl $0x3,%rax 0x000000000040055c <main+68>: mov %rax,%rdx 0x000000000040055f <main+71>: mov 0x2003c2(%rip),%rax # 0x600928 <environ@@glibc_2.2.5> 0x0000000000400566 <main+78>: lea (%rdx,%rax,1),%rax 0x000000000040056a <main+82>: mov (%rax),%rax 0x000000000040056d <main+85>: test %rax,%rax 0x0000000000400570 <main+88>: jne 0x400530 <main+24> 0x0000000000400572 <main+90>: mov $0x0,%eax 0x0000000000400577 <main+95>: leaveq 0x0000000000400578 <main+96>: retq end of assembler dump.
what don't understand block:
0x000000000040052e <main+22>: jmp 0x400553 <main+59> 0x0000000000400530 <main+24>: mov -0x4(%rbp),%eax 0x0000000000400533 <main+27>: cltq 0x0000000000400535 <main+29>: shl $0x3,%rax 0x0000000000400539 <main+33>: mov %rax,%rdx 0x000000000040053c <main+36>: mov 0x2003e5(%rip),%rax # 0x600928 <environ@@glibc_2.2.5> 0x0000000000400543 <main+43>: lea (%rdx,%rax,1),%rax 0x0000000000400547 <main+47>: mov (%rax),%rdi 0x000000000040054a <main+50>: addl $0x1,-0x4(%rbp) 0x000000000040054e <main+54>: callq 0x400418 <puts@plt> 0x0000000000400553 <main+59>: mov -0x4(%rbp),%eax 0x0000000000400556 <main+62>: cltq 0x0000000000400558 <main+64>: shl $0x3,%rax 0x000000000040055c <main+68>: mov %rax,%rdx 0x000000000040055f <main+71>: mov 0x2003c2(%rip),%rax # 0x600928 <environ@@glibc_2.2.5> 0x0000000000400566 <main+78>: lea (%rdx,%rax,1),%rax 0x000000000040056a <main+82>: mov (%rax),%rax 0x000000000040056d <main+85>: test %rax,%rax 0x0000000000400570 <main+88>: jne 0x400530 <main+24>
cltq promotes int int64. shl 3, %rax makes offset 64-bit pointer (multiplies whatever in rax 8). code doing looping through list of pointers environment variables. when finds value of zero, that's end, , drops out of loop.
here visual on how linux stores environment variables in ram, above stack. you'll see pointers starting @ 0xbffff75c; points 0xbffff893, "term=rxvt".
jcomeau@intrepid:/tmp$ gdb test gnu gdb (gdb) 7.2-debian copyright (c) 2010 free software foundation, inc. license gplv3+: gnu gpl version 3 or later <http://gnu.org/licenses/gpl.html> free software: free change , redistribute it. there no warranty, extent permitted law. type "show copying" , "show warranty" details. gdb configured "i486-linux-gnu". bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>... reading symbols /tmp/test...(no debugging symbols found)...done. (gdb) break main breakpoint 1 @ 0x80483e7 (gdb) run starting program: /tmp/test breakpoint 1, 0x080483e7 in main () (gdb) info reg eax 0xbffff754 -1073744044 ecx 0xe88ed1c 243854620 edx 0x1 1 ebx 0xb7fc5ff4 -1208197132 esp 0xbffff6a8 0xbffff6a8 ebp 0xbffff6a8 0xbffff6a8 esi 0x0 0 edi 0x0 0 eip 0x80483e7 0x80483e7 <main+3> eflags 0x200246 [ pf zf if id ] cs 0x73 115 ss 0x7b 123 ds 0x7b 123 es 0x7b 123 fs 0x0 0 gs 0x33 51 (gdb) x/160x 0xbffff6a8 0xbffff6a8: 0xbffff728 0xb7e86e46 0x00000001 0xbffff754 0xbffff6b8: 0xbffff75c 0xb7fe2940 0xb7ff7351 0xffffffff 0xbffff6c8: 0xb7ffeff4 0x08048254 0x00000001 0xbffff710 0xbffff6d8: 0xb7ff0976 0xb7fffac0 0xb7fe2c38 0xb7fc5ff4 0xbffff6e8: 0x00000000 0x00000000 0xbffff728 0x21b99b0c 0xbffff6f8: 0x0e88ed1c 0x00000000 0x00000000 0x00000000 0xbffff708: 0x00000001 0x08048330 0x00000000 0xb7ff64f0 0xbffff718: 0xb7e86d6b 0xb7ffeff4 0x00000001 0x08048330 0xbffff728: 0x00000000 0x08048351 0x080483e4 0x00000001 0xbffff738: 0xbffff754 0x08048440 0x08048430 0xb7ff12f0 0xbffff748: 0xbffff74c 0xb7fff908 0x00000001 0xbffff889 0xbffff758: 0x00000000 0xbffff893 0xbffff89d 0xbffff8ad 0xbffff768: 0xbffff8fd 0xbffff90c 0xbffff91c 0xbffff92d 0xbffff778: 0xbffff93a 0xbffff94d 0xbffff97a 0xbffffe6a 0xbffff788: 0xbffffe75 0xbffffef7 0xbfffff0e 0xbfffff1d 0xbffff798: 0xbfffff26 0xbfffff30 0xbfffff41 0xbfffff6a 0xbffff7a8: 0xbfffff73 0xbfffff8a 0xbfffff9d 0xbfffffa5 0xbffff7b8: 0xbfffffbc 0xbfffffcc 0xbfffffdf 0x00000000 0xbffff7c8: 0x00000020 0xffffe420 0x00000021 0xffffe000 0xbffff7d8: 0x00000010 0x078bfbff 0x00000006 0x00001000 0xbffff7e8: 0x00000011 0x00000064 0x00000003 0x08048034 0xbffff7f8: 0x00000004 0x00000020 0x00000005 0x00000008 0xbffff808: 0x00000007 0xb7fe3000 0x00000008 0x00000000 ---type <return> continue, or q <return> quit--- 0xbffff818: 0x00000009 0x08048330 0x0000000b 0x000003e8 0xbffff828: 0x0000000c 0x000003e8 0x0000000d 0x000003e8 0xbffff838: 0x0000000e 0x000003e8 0x00000017 0x00000000 0xbffff848: 0x00000019 0xbffff86b 0x0000001f 0xbffffff2 0xbffff858: 0x0000000f 0xbffff87b 0x00000000 0x00000000 0xbffff868: 0x50000000 0x7d410985 0x1539ef2a 0x7a3f5e9a 0xbffff878: 0x6964fe17 0x00363836 0x00000000 0x00000000 0xbffff888: 0x6d742f00 0x65742f70 0x54007473 0x3d4d5245 0xbffff898: 0x74767872 0x45485300 0x2f3d4c4c 0x2f6e6962 0xbffff8a8: 0x68736162 0x47445800 0x5345535f 0x4e4f4953 0xbffff8b8: 0x4f4f435f 0x3d45494b 0x37303534 0x66656135 0xbffff8c8: 0x32353131 0x63346334 0x30393436 0x35386331 0xbffff8d8: 0x39346134 0x37316135 0x3033312d 0x31383339 0xbffff8e8: 0x2e303736 0x31303832 0x382d3033 0x33323731 0xbffff8f8: 0x39373936 0x53494800 0x5a495354 0x30313d45 0xbffff908: 0x00303030 0x48535548 0x49474f4c 0x41463d4e 0xbffff918: 0x0045534c 0x444e4957 0x4449574f 0x3833383d (gdb) x/20s 0xbffff888 0xbffff888: "" 0xbffff889: "/tmp/test" 0xbffff893: "term=rxvt" 0xbffff89d: "shell=/bin/bash" 0xbffff8ad: "xdg_session_cookie=45075aef11524c4c64901c854a495a17-1309381670.280130-817236979" 0xbffff8fd: "histsize=10000" 0xbffff90c: "hushlogin=false" 0xbffff91c: "windowid=8388614" 0xbffff92d: "user=jcomeau" 0xbffff93a: "histfilesize=10000" 0xbffff94d: "ld_library_path=/usr/src/jet/lib/x86/shared:" 0xbffff97a: "ls_colors=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31"... 0xbffffa42: ":*.taz=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.zip=01;31:*.z=01;31:*.z=01;31:*.dz=01;31:*.gz=01;31:*.lz=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.d"... 0xbffffb0a: "eb=01;31:*.rpm=01;31:*.jar=01;31:*.rar=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35"... 0xbffffbd2: ":*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=---type <return> continue, or q <return> quit--- 01;35:*.m2v=01;35:*.mkv=01;35:*.ogm=01;35:*.mp4=01;35:*.m4"... 0xbffffc9a: "v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*."... 0xbffffd62: "yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;3"... 0xbffffe2a: "6:*.wav=00;36:*.axa=00;36:*.oga=00;36:*.spx=00;36:*.xspf=00;36:" 0xbffffe6a: "columns=80" 0xbffffe75: "path=/usr/src/jet/bin:/usr/local/bin:/usr/bin:/bin:/usr/games:/home/jcomeau:/home/jcomeau/bin:/home/jcomeau/src:/sbin:/usr/sbin:." (gdb) quit debugging session active. inferior 1 [process 10880] killed. quit anyway? (y or n) y
your compiler apparently smart enough optimize simply-formatted printf
puts
. fetching of environment string, , postincrement of i, right there in code. if don't figure of out on own you'll never understand it. "be" computer, , step through loop, using data dumped out gdb, , should become clear you.
Comments
Post a Comment