Copy [0x00400730]> pdf @ sym.f
/ (fcn) sym.f 907
| sym.f ();
| ; var int local_1dh @ rbp-0x1d
| ; var int local_1ch @ rbp-0x1c
| ; var int local_18h @ rbp-0x18
| ; var int local_14h @ rbp-0x14
| ; var int local_10h @ rbp-0x10
| ; var int local_8h @ rbp-0x8
| ; CALL XREF from 0x00400c3a (main)
| 0x0040081d push rbp
| 0x0040081e mov rbp, rsp
| 0x00400821 sub rsp, 0x20
| 0x00400825 mov dword [obj.student_num], 0 ; [0x602028:4]=0
| ; JMP XREF from 0x00400ba3 (sym.f)
| .-> 0x0040082f mov edi, str.1._Add_student.__2._Name_student.__3._Write_memo__4._Show_Name__5._Show_memo.__6._Bye_: ; 0x400ce8 ; "1. Add student.\n2. Name student.\n3. Write memo\n4. Show Name\n5. Show memo.\n6. Bye :)" ; 循环开始
| : 0x00400834 call sym.imp.puts ; int puts(const char *s)
| : 0x00400839 lea rax, [local_18h]
| : 0x0040083d mov rsi, rax
| : 0x00400840 mov edi, 0x400d3c
| : 0x00400845 mov eax, 0
| : 0x0040084a call sym.imp.__isoc99_scanf ; 读入选项到 [local_18h]
| : 0x0040084f call sym.imp.getchar ; int getchar(void)
| : 0x00400854 mov eax, dword [local_18h]
| : 0x00400857 cmp eax, 1 ; 1
| ,==< 0x0040085a jne 0x4008e8
| |: 0x00400860 mov eax, dword [obj.student_num] ; [0x602028:4]=0 ; 选项 1 ; 取出已有 student 数
| |: 0x00400866 cmp eax, 0x1d ; 29 ; 与最大值比较
| ,===< 0x00400869 jle 0x400889 ; 小于等于 30 时跳转
| ||: 0x0040086b mov edi, str.Exception_has_occurred._Jump ; 0x400d3f ; 否则调用 longjmp 返回到 main
| ||: 0x00400870 call sym.imp.puts ; int puts(const char *s)
| ||: 0x00400875 mov rax, qword [obj.jmpbuf] ; [0x602038:8]=0 ; 取出 jmpbuf 结构体
| ||: 0x0040087c mov esi, 0x1bf52 ; setjmp 返回值为 0x1bf52
| ||: 0x00400881 mov rdi, rax
| ||: 0x00400884 call sym.imp.longjmp ; longjmp(jmpbuf, 0x1bf52)
| ||: ; JMP XREF from 0x00400869 (sym.f)
| `---> 0x00400889 mov edi, 0x30 ; '0' ; 48
| |: 0x0040088e call sym.imp.malloc ; malloc(0x30) ; 分配一个 student 结构
| |: 0x00400893 mov qword [local_8h], rax ; 将 student 地址放到 [local_8h]
| |: 0x00400897 mov eax, dword [obj.student_num] ; [0x602028:4]=0
| |: 0x0040089d movsxd rdx, eax
| |: 0x004008a0 mov rax, qword [local_8h]
| |: 0x004008a4 mov qword [rax], rdx ; 将 student_num 作为该 student->id
| |: 0x004008a7 mov edi, 0x20 ; 32
| |: 0x004008ac call sym.imp.malloc ; malloc(0x20) ; 分配一块空间作为 name
| |: 0x004008b1 mov rdx, rax
| |: 0x004008b4 mov rax, qword [local_8h]
| |: 0x004008b8 mov qword [rax + 0x28], rdx ; 将 name 的地址放到 student->name
| |: 0x004008bc mov rax, qword [obj.my_class] ; [0x602030:8]=0
| |: 0x004008c3 mov edx, dword [obj.student_num] ; [0x602028:4]=0
| |: 0x004008c9 movsxd rdx, edx
| |: 0x004008cc mov rcx, qword [local_8h]
| |: 0x004008d0 mov qword [rax + rdx*8], ; 将新分配的 student 地址放到 my_class[id]
| |: 0x004008d4 mov eax, dword [obj.student_num] ; [0x602028:4]=0
| |: 0x004008da add eax, 1 ; student_num + 1
| |: 0x004008dd mov dword [obj.student_num], eax ; [0x602028:4]=0 ; 写回 student_num
| ,===< 0x004008e3 jmp 0x400ba3 ; 回到菜单
| ||: ; JMP XREF from 0x0040085a (sym.f)
| |`--> 0x004008e8 mov eax, dword [local_18h]
| | : 0x004008eb cmp eax, 2 ; 2
| |,==< 0x004008ee jne 0x4009b3
| ||: 0x004008f4 mov esi, 0x400d5d ; 选项 2
| ||: 0x004008f9 mov edi, 0x400d61
| ||: 0x004008fe mov eax, 0
| ||: 0x00400903 call sym.imp.printf ; int printf(const char *format)
| ||: 0x00400908 lea rax, [local_1ch]
| ||: 0x0040090c mov rsi, rax
| ||: 0x0040090f mov edi, 0x400d3c
| ||: 0x00400914 mov eax, 0
| ||: 0x00400919 call sym.imp.__isoc99_scanf ; 读入 id 到 [local_1ch]
| ||: 0x0040091e call sym.imp.getchar ; int getchar(void)
| ||: 0x00400923 mov edx, dword [local_1ch]
| ||: 0x00400926 mov eax, dword [obj.student_num] ; [0x602028:4]=0
| ||: 0x0040092c cmp edx, eax ; 判断 id 是否有效
| ,====< 0x0040092e jge 0x400937 ; 无效时跳转
| |||: 0x00400930 mov eax, dword [local_1ch]
| |||: 0x00400933 test eax, eax ; 根据 id 设置符号位
| ,=====< 0x00400935 jns 0x40094b ; 符号位为 0 时跳转,即 id 大于等于 0
| ||||: ; JMP XREF from 0x0040092e (sym.f)
| |`----> 0x00400937 mov edi, str.Invalid_ID. ; 0x400d64 ; "Invalid ID."
| | ||: 0x0040093c call sym.imp.puts ; int puts(const char *s)
| | ||: 0x00400941 mov edi, 1
| | ||: 0x00400946 call sym.imp.exit ; void exit(int status)
| | ||: ; JMP XREF from 0x00400935 (sym.f)
| `-----> 0x0040094b mov esi, str.Input_name: ; 0x400d70 ; "Input name:"
| ||: 0x00400950 mov edi, 0x400d61
| ||: 0x00400955 mov eax, 0
| ||: 0x0040095a call sym.imp.printf ; int printf(const char *format)
| ||: 0x0040095f mov rax, qword [obj.my_class] ; [0x602030:8]=0
| ||: 0x00400966 mov edx, dword [local_1ch]
| ||: 0x00400969 movsxd rdx, edx
| ||: 0x0040096c mov rax, qword [rax + rdx*8] ; 取出 my_class[id]
| ||: 0x00400970 mov rax, qword [rax + 0x28] ; [0x28:8]=-1 ; 取出 my_class[id]->name
| ||: 0x00400974 mov qword [local_10h], rax ; 放到 [local_10h]
| ||: 0x00400978 mov dword [local_14h], 0 ; 循环计数 i 初始化为 0
| ,====< 0x0040097f jmp 0x4009a8 ; 进入循环
| |||: ; JMP XREF from 0x004009ac (sym.f)
| .-----> 0x00400981 call sym.imp.getchar ; int getchar(void)
| :|||: 0x00400986 mov byte [local_1dh], al ; 读入一个字节到 [local_1dh]
| :|||: 0x00400989 cmp byte [local_1dh], 0xa ; [0xa:1]=255 ; 10
| ,======< 0x0040098d jne 0x400995 ; 非换行符时跳转
| |:|||: 0x0040098f nop
| ,=======< 0x00400990 jmp 0x400ba3 ; 否则回到菜单
| ||:|||: ; JMP XREF from 0x0040098d (sym.f)
| |`------> 0x00400995 mov rax, qword [local_10h]
| | :|||: 0x00400999 movzx edx, byte [local_1dh]
| | :|||: 0x0040099d mov byte [rax], dl ; 写入该字节写入 name
| | :|||: 0x0040099f add qword [local_10h], 1 ; name = name + 1
| | :|||: 0x004009a4 add dword [local_14h], 1 ; i = i + 1
| | :|||: ; JMP XREF from 0x0040097f (sym.f)
| | :`----> 0x004009a8 cmp dword [local_14h], 0x20 ; [0x20:4]=-1 ; 32
| | `=====< 0x004009ac jle 0x400981 ; 当小于等于 32 字节时继续循环,即读入 33 字节,存在溢出
| | ,====< 0x004009ae jmp 0x400ba3 ; 否则回到菜单
| | |||: ; JMP XREF from 0x004008ee (sym.f)
| | ||`--> 0x004009b3 mov eax, dword [local_18h]
| | || : 0x004009b6 cmp eax, 3 ; 3
| | ||,==< 0x004009b9 jne 0x400a7e
| | |||: 0x004009bf mov esi, 0x400d5d ; 选项 3
| | |||: 0x004009c4 mov edi, 0x400d61
| | |||: 0x004009c9 mov eax, 0
| | |||: 0x004009ce call sym.imp.printf ; int printf(const char *format)
| | |||: 0x004009d3 lea rax, [local_1ch]
| | |||: 0x004009d7 mov rsi, rax
| | |||: 0x004009da mov edi, 0x400d3c
| | |||: 0x004009df mov eax, 0
| | |||: 0x004009e4 call sym.imp.__isoc99_scanf ; 读入 id 到 [local_1ch]
| | |||: 0x004009e9 call sym.imp.getchar ; int getchar(void)
| | |||: 0x004009ee mov edx, dword [local_1ch]
| | |||: 0x004009f1 mov eax, dword [obj.student_num] ; [0x602028:4]=0
| | |||: 0x004009f7 cmp edx, eax ; 判断 id 是否有效
| | ,=====< 0x004009f9 jge 0x400a02 ; 无效时跳转
| | ||||: 0x004009fb mov eax, dword [local_1ch]
| | ||||: 0x004009fe test eax, eax ; 根据 id 设置符号位
| |,======< 0x00400a00 jns 0x400a16 ; 符号位为 0 时跳转,即 id 大于等于 0
| ||||||: ; JMP XREF from 0x004009f9 (sym.f)
| ||`-----> 0x00400a02 mov edi, str.Invalid_ID. ; 0x400d64 ; "Invalid ID."
| || |||: 0x00400a07 call sym.imp.puts ; int puts(const char *s)
| || |||: 0x00400a0c mov edi, 1
| || |||: 0x00400a11 call sym.imp.exit ; void exit(int status)
| || |||: ; JMP XREF from 0x00400a00 (sym.f)
| |`------> 0x00400a16 mov esi, str.Input_memo: ; 0x400d7c ; "Input memo:"
| | |||: 0x00400a1b mov edi, 0x400d61
| | |||: 0x00400a20 mov eax, 0
| | |||: 0x00400a25 call sym.imp.printf ; int printf(const char *format)
| | |||: 0x00400a2a mov rax, qword [obj.my_class] ; [0x602030:8]=0
| | |||: 0x00400a31 mov edx, dword [local_1ch]
| | |||: 0x00400a34 movsxd rdx, edx
| | |||: 0x00400a37 mov rax, qword [rax + rdx*8] ; 取出 my_class[id]
| | |||: 0x00400a3b add rax, 8 ; 取出 my_class[id]->memo
| | |||: 0x00400a3f mov qword [local_10h], rax ; 放到 [local_10h]
| | |||: 0x00400a43 mov dword [local_14h], 0 ; 循环计数 i,初始化为 0
| | ,=====< 0x00400a4a jmp 0x400a73 ; 进入循环
| | ||||: ; JMP XREF from 0x00400a77 (sym.f)
| |.------> 0x00400a4c call sym.imp.getchar ; int getchar(void)
| |:||||: 0x00400a51 mov byte [local_1dh], al
| |:||||: 0x00400a54 cmp byte [local_1dh], 0xa ; [0xa:1]=255 ; 10
| ========< 0x00400a58 jne 0x400a60
| |:||||: 0x00400a5a nop
| ========< 0x00400a5b jmp 0x400ba3
| |:||||: ; JMP XREF from 0x00400a58 (sym.f)
| --------> 0x00400a60 mov rax, qword [local_10h]
| |:||||: 0x00400a64 movzx edx, byte [local_1dh]
| |:||||: 0x00400a68 mov byte [rax], dl
| |:||||: 0x00400a6a add qword [local_10h], 1
| |:||||: 0x00400a6f add dword [local_14h], 1
| |:||||: ; JMP XREF from 0x00400a4a (sym.f)
| |:`-----> 0x00400a73 cmp dword [local_14h], 0x20 ; [0x20:4]=-1 ; 32
| |`======< 0x00400a77 jle 0x400a4c ; 当小于等于 32 字节时继续循环,即读入 33 字节,存在溢出
| | ,=====< 0x00400a79 jmp 0x400ba3 ; 否则回到菜单
| | ||||: ; JMP XREF from 0x004009b9 (sym.f)
| | |||`--> 0x00400a7e mov eax, dword [local_18h]
| | ||| : 0x00400a81 cmp eax, 4 ; 4
| | |||,==< 0x00400a84 jne 0x400b0d
| | ||||: 0x00400a8a mov esi, 0x400d5d ; 选项 4
| | ||||: 0x00400a8f mov edi, 0x400d61
| | ||||: 0x00400a94 mov eax, 0
| | ||||: 0x00400a99 call sym.imp.printf ; int printf(const char *format)
| | ||||: 0x00400a9e lea rax, [local_1ch]
| | ||||: 0x00400aa2 mov rsi, rax
| | ||||: 0x00400aa5 mov edi, 0x400d3c
| | ||||: 0x00400aaa mov eax, 0
| | ||||: 0x00400aaf call sym.imp.__isoc99_scanf ; 读入 id 到 [local_1ch]
| | ||||: 0x00400ab4 call sym.imp.getchar ; int getchar(void)
| | ||||: 0x00400ab9 mov edx, dword [local_1ch]
| | ||||: 0x00400abc mov eax, dword [obj.student_num] ; [0x602028:4]=0
| | ||||: 0x00400ac2 cmp edx, eax ; 判断 id 是否有效
| |,======< 0x00400ac4 jge 0x400acd ; 无效时跳转
| ||||||: 0x00400ac6 mov eax, dword [local_1ch]
| ||||||: 0x00400ac9 test eax, eax ; 根据 id 设置符号位
| ========< 0x00400acb jns 0x400ae1 ; 符号位为 0 时跳转,即 id 大于等于 0
| ||||||: ; JMP XREF from 0x00400ac4 (sym.f)
| |`------> 0x00400acd mov edi, str.Invalid_ID. ; 0x400d64 ; "Invalid ID."
| | ||||: 0x00400ad2 call sym.imp.puts ; int puts(const char *s)
| | ||||: 0x00400ad7 mov edi, 1
| | ||||: 0x00400adc call sym.imp.exit ; void exit(int status)
| | ||||: ; JMP XREF from 0x00400acb (sym.f)
| --------> 0x00400ae1 mov rax, qword [obj.my_class] ; [0x602030:8]=0
| | ||||: 0x00400ae8 mov edx, dword [local_1ch]
| | ||||: 0x00400aeb movsxd rdx, edx
| | ||||: 0x00400aee mov rax, qword [rax + rdx*8] ; 取出 my_class[id]
| | ||||: 0x00400af2 mov rax, qword [rax + 0x28] ; [0x28:8]=-1 ; 取出 my_class[id]->name
| | ||||: 0x00400af6 mov rsi, rax
| | ||||: 0x00400af9 mov edi, 0x400d61
| | ||||: 0x00400afe mov eax, 0
| | ||||: 0x00400b03 call sym.imp.printf ; 打印出 my_class[id]->name
| |,======< 0x00400b08 jmp 0x400ba3 ; 回到菜单
| ||||||: ; JMP XREF from 0x00400a84 (sym.f)
| |||||`--> 0x00400b0d mov eax, dword [local_18h]
| ||||| : 0x00400b10 cmp eax, 5 ; 5
| |||||,==< 0x00400b13 jne 0x400b99
| ||||||: 0x00400b19 mov esi, 0x400d5d ; 选项 5
| ||||||: 0x00400b1e mov edi, 0x400d61
| ||||||: 0x00400b23 mov eax, 0
| ||||||: 0x00400b28 call sym.imp.printf ; int printf(const char *format)
| ||||||: 0x00400b2d lea rax, [local_1ch]
| ||||||: 0x00400b31 mov rsi, rax
| ||||||: 0x00400b34 mov edi, 0x400d3c
| ||||||: 0x00400b39 mov eax, 0
| ||||||: 0x00400b3e call sym.imp.__isoc99_scanf ; 读入 id 到 [local_1ch]
| ||||||: 0x00400b43 call sym.imp.getchar ; int getchar(void)
| ||||||: 0x00400b48 mov edx, dword [local_1ch]
| ||||||: 0x00400b4b mov eax, dword [obj.student_num] ; [0x602028:4]=0
| ||||||: 0x00400b51 cmp edx, eax ; 判断 id 是否有效
| ========< 0x00400b53 jge 0x400b5c ; 无效时跳转
| ||||||: 0x00400b55 mov eax, dword [local_1ch]
| ||||||: 0x00400b58 test eax, eax ; 根据 id 设置符号位
| ========< 0x00400b5a jns 0x400b70 ; 符号位为 0 时跳转,即 id 大于等于 0
| ||||||: ; JMP XREF from 0x00400b53 (sym.f)
| --------> 0x00400b5c mov edi, str.Invalid_ID. ; 0x400d64 ; "Invalid ID."
| ||||||: 0x00400b61 call sym.imp.puts ; int puts(const char *s)
| ||||||: 0x00400b66 mov edi, 1
| ||||||: 0x00400b6b call sym.imp.exit ; void exit(int status)
| ||||||: ; JMP XREF from 0x00400b5a (sym.f)
| --------> 0x00400b70 mov rax, qword [obj.my_class] ; [0x602030:8]=0
| ||||||: 0x00400b77 mov edx, dword [local_1ch]
| ||||||: 0x00400b7a movsxd rdx, edx
| ||||||: 0x00400b7d mov rax, qword [rax + rdx*8] ; 取出 my_class[id]
| ||||||: 0x00400b81 add rax, 8 ; 取出 my_class[id]->memo
| ||||||: 0x00400b85 mov rsi, rax
| ||||||: 0x00400b88 mov edi, 0x400d61
| ||||||: 0x00400b8d mov eax, 0
| ||||||: 0x00400b92 call sym.imp.printf ; 打印出 my_class[id]->memo
| ========< 0x00400b97 jmp 0x400ba3 ; 回到菜单
| ||||||: ; JMP XREF from 0x00400b13 (sym.f)
| |||||`--> 0x00400b99 mov edi, 0
| ||||| : 0x00400b9e call sym.imp.exit ; void exit(int status)
| ||||| | ; XREFS: JMP 0x00400b97 JMP 0x00400b08 JMP 0x00400a79 JMP 0x00400a5b JMP 0x004009ae JMP 0x00400990 JMP 0x004008e3
\ `````-`=< 0x00400ba3 jmp 0x40082f ; 循环继续
[0x00400730]> is ~student_num
048 0x00002028 0x00602028 GLOBAL OBJECT 4 student_num