汇编语言中的getchar()
这是一个简单的C程序:汇编语言中的getchar(),c,gcc,assembly,getchar,C,Gcc,Assembly,Getchar,这是一个简单的C程序: #include <stdio.h> int main(){ getchar(); return 0; } 在“main”中,有一个对“getchar”函数的调用。可以看到这个函数的代码(当然是汇编代码)吗 特别是,我会理解“getchar()”背后的键盘中断机制。如果您想要ASM输出,您只需请求gdb加载您的C程序并为您反汇编getchar。 这将给出如下内容(在我的系统上): $gdb/bin/cat (gdb)运行 启动程序:/bin
#include <stdio.h>
int main(){
getchar();
return 0;
}
在“main”中,有一个对“getchar”函数的调用。可以看到这个函数的代码(当然是汇编代码)吗
特别是,我会理解“getchar()”背后的键盘中断机制。如果您想要ASM输出,您只需请求
gdb
加载您的C程序并为您反汇编getchar
。
这将给出如下内容(在我的系统上):
$gdb/bin/cat
(gdb)运行
启动程序:/bin/cat
^C
程序收到信号SIGINT,中断。
0x00007FF7B0C5C0位于../sysdeps/unix/syscall template.S:81处的u read_nocancel()中
(gdb)disas getchar
函数getchar的汇编程序代码转储:
0x00007FF7AA4B30:推送%rbx
0x00007ffff7aa4b31:mov 0x332be0(%rip),%rbx#0x7ffff7dd7718
0x00007FF7AA4B38:mov(%rbx),%eax
0x00007FF7AA4B3A:mov%rbx,%rdi
0x00007FF7AA4B3D:和$0x8000,%eax
0x00007FF7AA4B42:jne 0x7FF7AA4B9E
0x00007FF7AA4B44:mov 0x88(%rbx),%rdx
0x00007FF7AA4B4B4B:mov%fs:0x10,%r8
0x00007FF7AA4B54:cmp 0x8(%rdx),%r8
0x00007FF7AA4B58:je 0x7FF7AA4Bf0
0x00007FF7AA4B5E:mov$0x1,%esi
0x00007ffff7aa4b63:cmpl$0x0,0x336c6a(%rip)#0x7ffff7ddb7d4
0x00007FF7AA4B6A:je 0x7FF7AA4B78
0x00007FF7AA4B6C:锁定cmpxchg%esi,(%rdx)
0x00007FF7AA4B70:jne 0x7FF7AA4C41
0x00007FF7AA4B76:jmp 0x7FF7AA4B81
0x00007FF7AA4B78:cmpxchg%esi,(%rdx)
0x00007FF7AA4B7B:jne 0x7FF7AA4C41
0x00007FF7AA4B81:mov 0x88(%rbx),%rax
0x00007FF7AA4B88:mov 0x88(%rbx),%rdx
0x00007ffff7aa4b8f:mov 0x332b82(%rip),%rdi#0x7ffff7dd7718
0x00007FF7AA4B96:mov%r8,0x8(%rax)
0x00007FF7AA4B9A:添加$0x1,0x4(%rdx)
0x00007FF7AA4B9E:mov 0x8(%rdi),%rax
0x00007FF7AA4BA2:cmp 0x10(%rdi),%rax
0x00007FF7AA4BA6:jae 0x7ffff7aa4bf5
0x00007FF7AA4BA8:lea 0x1(%rax),%rdx
0x00007FF7AA4BAC:mov%rdx,0x8(%rdi)
0x00007FF7AA4BB0:movzbl(%rax),%edx
0x00007FF7AA4BB3:testl$0x8000,(%rbx)
0x00007FF7AA4BB9:jne 0x7FF7AA4BE4
0x00007FF7AA4BBBB:mov 0x88(%rbx),%rsi
0x00007FF7AA4BC2:subl$0x1,0x4(%rsi)
0x00007FF7AA4BC6:jne 0x7FF7AA4BE4
0x00007FF7AA4BC8:movq$0x0,0x8(%rsi)
0x00007ffff7aa4bd0:cmpl$0x0,0x336bfd(%rip)#0x7ffff7ddb7d4
0x00007FF7AA4BD7:je 0x7FF7AA4BE0
0x00007FF7AA4BD9:锁定声明(%rsi)
0x00007FF7AA4BDC:jne 0x7FF7AA4C5C
0x00007FF7AA4BDE:jmp 0x7FF7AA4BE4
0x00007FF7AA4BE0:decl(%rsi)
0x00007FF7AA4BE2:jne 0x7ffff7aa4c5c
0x00007FF7AA4BE4:mov%edx,%eax
0x00007FF7AA4BE6:弹出%rbx
0x00007FF7AA4BE7:retq
0x00007ffff7aa4be8:nopl 0x0(%rax,%rax,1)
0x00007FF7AA4BF0:mov%rbx,%rdi
0x00007FF7AA4BF3:jmp 0x7FF7AA4B9A
0x00007FF7AA4BF5:callq 0x7FF7AA9060
0x00007FF7AA4BFA:mov%eax,%edx
0x00007FF7AA4BFC:jmp 0x7FF7AA4BB3
0x00007FF7AA4BFE:testl$0x8000,(%rbx)
0x00007FF7AA4C04:mov%rax,%rsi
0x00007FF7AA4C07:jne 0x7FF7AA4C39
0x00007FF7AA4C09:mov 0x88(%rbx),%rdx
0x00007FF7AA4C10:mov 0x4(%rdx),%eax
0x00007FF7AA4C13:lea-0x1(%rax),%ecx
0x00007FF7AA4C16:测试%ecx,%ecx
0x00007FF7AA4C18:mov%ecx,0x4(%rdx)
0x00007FF7AA4C1B:jne 0x7FF7AA4C39
0x00007FF7AA4C1D:movq$0x0,0x8(%rdx)
0x00007FF7AA4C25:cmpl$0x0,0x336ba8(%rip)#0x7ffff7ddb7d4
0x00007FF7AA4C2C:je 0x7ffff7aa4c35
0x00007FF7AA4C2E:锁定decl(%rdx)
0x00007FF7AA4C31:jne 0x7FF7AA4C77
0x00007FF7AA4C33:jmp 0x7FF7AA4C39
0x00007FF7AA4C35:decl(%rdx)
0x00007FF7AA4C37:jne 0x7FF7AA4C77
0x00007FF7AA4C39:mov%rsi,%rdi
0x00007FF7AA4C3C:调用0x7ffff7a54d50
汇编程序转储结束。
您也可以直接查看getchar是如何实现的,但是这将为您提供C代码(有时可能是神秘的)。如果您想要ASM输出,您只需请求
gdb
加载您的C程序并为您反汇编getchar
。
这将给出如下内容(在我的系统上):
$gdb/bin/cat
(gdb)运行
启动程序:/bin/cat
^C
程序收到信号SIGINT,中断。
0x00007FF7B0C5C0位于../sysdeps/unix/syscall template.S:81处的u read_nocancel()中
(gdb)disas getchar
函数getchar的汇编程序代码转储:
0x00007FF7AA4B30:推送%rbx
0x00007ffff7aa4b31:mov 0x332be0(%rip),%rbx#0x7ffff7dd7718
0x00007FF7AA4B38:mov(%rbx),%eax
0x00007FF7AA4B3A:mov%rbx,%rdi
0x00007FF7AA4B3D:和$0x8000,%eax
0x00007FF7AA4B42:jne 0x7FF7AA4B9E
0x00007FF7AA4B44:mov 0x88(%rbx),%rdx
0x00007FF7AA4B4B4B:mov%fs:0x10,%r8
0x00007FF7AA4B54:cmp 0x8(%rdx),%r8
0x00007FF7AA4B58:je 0x7FF7AA4Bf0
0x00007FF7AA4B5E:mov$0x1,%esi
0x00007ffff7aa4b63:cmpl$0x0,0x336c6a(%rip)#0x7ffff7ddb7d4
0x00007FF7AA4B6A:je 0x7FF7AA4B78
0x00007FF7AA4B6C:锁定cmpxchg%esi,(%rdx)
0x00007FF7AA4B70:jne 0x7FF7AA4C41
0x00007FF7AA4B76:jmp 0x7FF7AA4B81
0x00007FF7AA4B78:cmpxchg%esi,(%rdx)
0x00007FF7AA4B7B:jne 0x7FF7AA4C41
0x00007FF7AA4B81:mov 0x88(%rbx),%rax
0x00007FF7AA4B88:mov 0x88(%rbx),%rdx
0x00007ffff7aa4b8f:mov 0x332b82(%rip),%rdi#0x7ffff7dd7718
0x00007FF7AA4B96:mov%r8,0x8(%rax)
0x00007FF7AA4B9A:添加$0x1,0x4(%rdx)
.file "prog.c"
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
andl $-16, %esp
call getchar
movl $0, %eax
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (Debian 4.8.2-1) 4.8.2"
.section .note.GNU-stack,"",@progbits
$ gdb /bin/cat
(gdb) run
Starting program: /bin/cat
^C
Program received signal SIGINT, Interrupt.
0x00007ffff7b0c5c0 in __read_nocancel () at ../sysdeps/unix/syscall-template.S:81
(gdb) disas getchar
Dump of assembler code for function getchar:
0x00007ffff7aa4b30 <+0>: push %rbx
0x00007ffff7aa4b31 <+1>: mov 0x332be0(%rip),%rbx # 0x7ffff7dd7718 <stdin>
0x00007ffff7aa4b38 <+8>: mov (%rbx),%eax
0x00007ffff7aa4b3a <+10>: mov %rbx,%rdi
0x00007ffff7aa4b3d <+13>: and $0x8000,%eax
0x00007ffff7aa4b42 <+18>: jne 0x7ffff7aa4b9e <getchar+110>
0x00007ffff7aa4b44 <+20>: mov 0x88(%rbx),%rdx
0x00007ffff7aa4b4b <+27>: mov %fs:0x10,%r8
0x00007ffff7aa4b54 <+36>: cmp 0x8(%rdx),%r8
0x00007ffff7aa4b58 <+40>: je 0x7ffff7aa4bf0 <getchar+192>
0x00007ffff7aa4b5e <+46>: mov $0x1,%esi
0x00007ffff7aa4b63 <+51>: cmpl $0x0,0x336c6a(%rip) # 0x7ffff7ddb7d4 <__libc_multiple_threads>
0x00007ffff7aa4b6a <+58>: je 0x7ffff7aa4b78 <getchar+72>
0x00007ffff7aa4b6c <+60>: lock cmpxchg %esi,(%rdx)
0x00007ffff7aa4b70 <+64>: jne 0x7ffff7aa4c41 <_L_lock_30>
0x00007ffff7aa4b76 <+70>: jmp 0x7ffff7aa4b81 <getchar+81>
0x00007ffff7aa4b78 <+72>: cmpxchg %esi,(%rdx)
0x00007ffff7aa4b7b <+75>: jne 0x7ffff7aa4c41 <_L_lock_30>
0x00007ffff7aa4b81 <+81>: mov 0x88(%rbx),%rax
0x00007ffff7aa4b88 <+88>: mov 0x88(%rbx),%rdx
0x00007ffff7aa4b8f <+95>: mov 0x332b82(%rip),%rdi # 0x7ffff7dd7718 <stdin>
0x00007ffff7aa4b96 <+102>: mov %r8,0x8(%rax)
0x00007ffff7aa4b9a <+106>: addl $0x1,0x4(%rdx)
0x00007ffff7aa4b9e <+110>: mov 0x8(%rdi),%rax
0x00007ffff7aa4ba2 <+114>: cmp 0x10(%rdi),%rax
0x00007ffff7aa4ba6 <+118>: jae 0x7ffff7aa4bf5 <getchar+197>
0x00007ffff7aa4ba8 <+120>: lea 0x1(%rax),%rdx
0x00007ffff7aa4bac <+124>: mov %rdx,0x8(%rdi)
0x00007ffff7aa4bb0 <+128>: movzbl (%rax),%edx
0x00007ffff7aa4bb3 <+131>: testl $0x8000,(%rbx)
0x00007ffff7aa4bb9 <+137>: jne 0x7ffff7aa4be4 <getchar+180>
0x00007ffff7aa4bbb <+139>: mov 0x88(%rbx),%rsi
0x00007ffff7aa4bc2 <+146>: subl $0x1,0x4(%rsi)
0x00007ffff7aa4bc6 <+150>: jne 0x7ffff7aa4be4 <getchar+180>
0x00007ffff7aa4bc8 <+152>: movq $0x0,0x8(%rsi)
0x00007ffff7aa4bd0 <+160>: cmpl $0x0,0x336bfd(%rip) # 0x7ffff7ddb7d4 <__libc_multiple_threads>
0x00007ffff7aa4bd7 <+167>: je 0x7ffff7aa4be0 <getchar+176>
0x00007ffff7aa4bd9 <+169>: lock decl (%rsi)
0x00007ffff7aa4bdc <+172>: jne 0x7ffff7aa4c5c <_L_unlock_79>
0x00007ffff7aa4bde <+174>: jmp 0x7ffff7aa4be4 <getchar+180>
0x00007ffff7aa4be0 <+176>: decl (%rsi)
0x00007ffff7aa4be2 <+178>: jne 0x7ffff7aa4c5c <_L_unlock_79>
0x00007ffff7aa4be4 <+180>: mov %edx,%eax
0x00007ffff7aa4be6 <+182>: pop %rbx
0x00007ffff7aa4be7 <+183>: retq
0x00007ffff7aa4be8 <+184>: nopl 0x0(%rax,%rax,1)
0x00007ffff7aa4bf0 <+192>: mov %rbx,%rdi
0x00007ffff7aa4bf3 <+195>: jmp 0x7ffff7aa4b9a <getchar+106>
0x00007ffff7aa4bf5 <+197>: callq 0x7ffff7aa9060 <__GI___uflow>
0x00007ffff7aa4bfa <+202>: mov %eax,%edx
0x00007ffff7aa4bfc <+204>: jmp 0x7ffff7aa4bb3 <getchar+131>
0x00007ffff7aa4bfe <+206>: testl $0x8000,(%rbx)
0x00007ffff7aa4c04 <+212>: mov %rax,%rsi
0x00007ffff7aa4c07 <+215>: jne 0x7ffff7aa4c39 <getchar+265>
0x00007ffff7aa4c09 <+217>: mov 0x88(%rbx),%rdx
0x00007ffff7aa4c10 <+224>: mov 0x4(%rdx),%eax
0x00007ffff7aa4c13 <+227>: lea -0x1(%rax),%ecx
0x00007ffff7aa4c16 <+230>: test %ecx,%ecx
0x00007ffff7aa4c18 <+232>: mov %ecx,0x4(%rdx)
0x00007ffff7aa4c1b <+235>: jne 0x7ffff7aa4c39 <getchar+265>
0x00007ffff7aa4c1d <+237>: movq $0x0,0x8(%rdx)
0x00007ffff7aa4c25 <+245>: cmpl $0x0,0x336ba8(%rip) # 0x7ffff7ddb7d4 <__libc_multiple_threads>
0x00007ffff7aa4c2c <+252>: je 0x7ffff7aa4c35 <getchar+261>
0x00007ffff7aa4c2e <+254>: lock decl (%rdx)
0x00007ffff7aa4c31 <+257>: jne 0x7ffff7aa4c77 <_L_unlock_150>
0x00007ffff7aa4c33 <+259>: jmp 0x7ffff7aa4c39 <getchar+265>
0x00007ffff7aa4c35 <+261>: decl (%rdx)
0x00007ffff7aa4c37 <+263>: jne 0x7ffff7aa4c77 <_L_unlock_150>
0x00007ffff7aa4c39 <+265>: mov %rsi,%rdi
0x00007ffff7aa4c3c <+268>: callq 0x7ffff7a54d50 <_Unwind_Resume>
End of assembler dump.
$ gcc -o prog prog.c
$ gdb prog
...
(gdb) r
^C
(gdb) disas getchar
/* Copyright (C) 1993-2015 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
8
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public
15 License along with the GNU C Library; if not, see
16 <http://www.gnu.org/licenses/>.
17
18 As a special exception, if you link the code in this file with
19 files compiled with a GNU compiler to produce an executable,
20 that does not cause the resulting executable to be covered by
21 the GNU Lesser General Public License. This exception does not
22 however invalidate any other reasons why the executable file
23 might be covered by the GNU Lesser General Public License.
24 This exception applies to code released by its copyright holders
25 in files containing the exception. */
26
27 #include "libioP.h"
28 #include "stdio.h"
29
30 #undef getchar
31
32 int
33 getchar (void)
34 {
35 int result;
36 _IO_acquire_lock (_IO_stdin);
37 result = _IO_getc_unlocked (_IO_stdin);
38 _IO_release_lock (_IO_stdin);
39 return result;
40 }
41
42 #if defined weak_alias && !defined _IO_MTSAFE_IO
43 #undef getchar_unlocked
44 weak_alias (getchar, getchar_unlocked)
45 #endif