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

Popular posts from this blog

c# - SharpSVN - How to get the previous revision? -

c++ - Is it possible to compile a VST on linux? -

url - Querystring manipulation of email Address in PHP -