免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123下一页
最近访问板块 发新帖
查看: 4246 | 回复: 24
打印 上一主题 下一主题

[内核入门] trampoline.S代码疑问? [复制链接]

论坛徽章:
13
15-16赛季CBA联赛之八一
日期:2016-07-08 21:00:1415-16赛季CBA联赛之同曦
日期:2017-02-15 14:26:1515-16赛季CBA联赛之佛山
日期:2017-02-20 14:19:2615-16赛季CBA联赛之青岛
日期:2017-05-07 16:49:1115-16赛季CBA联赛之广夏
日期:2017-07-30 09:13:1215-16赛季CBA联赛之广东
日期:2018-07-05 22:34:3615-16赛季CBA联赛之江苏
日期:2018-09-03 12:10:2115-16赛季CBA联赛之上海
日期:2018-09-25 03:49:2215-16赛季CBA联赛之广东
日期:2018-09-25 04:09:12
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2016-03-30 14:28 |只看该作者 |倒序浏览
本帖最后由 _nosay 于 2016-03-30 16:29 编辑
  1. .code16

  2. ENTRY(trampoline_data)
  3. r_base = .

  4.         mov        %cs, %ax        # Code and data in the same place
  5.         mov        %ax, %ds

  6.         mov        $1, %bx                # Flag an SMP trampoline
  7.         cli                        # We should be safe anyway

  8.         movl        $0xA5A5A5A5, trampoline_data - r_base
复制代码
“r_base = .”,这行代码是什么意思?
“movl $0xA5A5A5A5, trampoline_data - r_base”,0xA5A5A5A5是存到什么位置去了?


写了一个测试程序:
就是在三个函数里,都写一行“r_base = .”,并把r_base值打印出来。
  1. #include <stdio.h>

  2. int fun1(int n)
  3. {
  4.         long base;

  5.         //printf("0x%x\n", (&n)[-1]);

  6. __asm__(
  7.         "r_base = .\n\t"
  8.         "movl r_base, %0\n\t"
  9.         :"=a"((long)base)
  10.         :"a"(0)
  11.         :
  12.         );

  13.         printf("0x%x\n", (unsigned int)base);

  14.         return 0;
  15. }

  16. int fun2(int n)
  17. {
  18.         long base;

  19.         //printf("0x%x\n", (&n)[-1]);

  20. __asm__(
  21.         "r_base = .\n\t"
  22.         "movl r_base, %0\n\t"
  23.         :"=a"((long)base)
  24.         :"a"(0)
  25.         :
  26.         );

  27.         printf("0x%x\n", (unsigned int)base);

  28.         return 0;
  29. }

  30. int fun3(int n)
  31. {
  32.         long base;

  33.         //printf("0x%x\n", (&n)[-1]);

  34. __asm__(
  35.         "r_base = .\n\t"
  36.         "movl r_base, %0\n\t"
  37.         :"=a"((long)base)
  38.         :"a"(0)
  39.         :
  40.         );

  41.         printf("0x%x\n", (unsigned int)base);

  42.         return 0;
  43. }

  44. int main()
  45. {
  46.         fun1(0);
  47.         fun2(0);
  48.         fun3(0);

  49.         return 0;
  50. }
复制代码
打印结果:
[120] $ ./a.out
0x4841ba1
0x48448a1
0x48475a1

fun2()比fun1()多了0x2d00,fun3()比fun2()多了0x2d00,请问为什么有这样的规律,r_base到底是什么?

论坛徽章:
13
15-16赛季CBA联赛之八一
日期:2016-07-08 21:00:1415-16赛季CBA联赛之同曦
日期:2017-02-15 14:26:1515-16赛季CBA联赛之佛山
日期:2017-02-20 14:19:2615-16赛季CBA联赛之青岛
日期:2017-05-07 16:49:1115-16赛季CBA联赛之广夏
日期:2017-07-30 09:13:1215-16赛季CBA联赛之广东
日期:2018-07-05 22:34:3615-16赛季CBA联赛之江苏
日期:2018-09-03 12:10:2115-16赛季CBA联赛之上海
日期:2018-09-25 03:49:2215-16赛季CBA联赛之广东
日期:2018-09-25 04:09:12
2 [报告]
发表于 2016-03-30 16:25 |只看该作者
总感觉0x4800000挺特别的。

执行:
objdump -S a.out | grep 0x48
readelf -a ./a.out | grep 0x48

什么都没看到

linux2.4.0:arch/i386/kernel/trampoline.S有一段这样的注释:
/ *        On entry to trampoline_data, the processor is in real mode
*        with 16-bit addressing and 16-bit data.  CS has some value
*        and IP is zero.  Thus, data addresses need to be absolute
*        (no relocation) and are taken with regard to r_base.
*/

但我还是不知道r_base值具体是什么东西

论坛徽章:
13
15-16赛季CBA联赛之八一
日期:2016-07-08 21:00:1415-16赛季CBA联赛之同曦
日期:2017-02-15 14:26:1515-16赛季CBA联赛之佛山
日期:2017-02-20 14:19:2615-16赛季CBA联赛之青岛
日期:2017-05-07 16:49:1115-16赛季CBA联赛之广夏
日期:2017-07-30 09:13:1215-16赛季CBA联赛之广东
日期:2018-07-05 22:34:3615-16赛季CBA联赛之江苏
日期:2018-09-03 12:10:2115-16赛季CBA联赛之上海
日期:2018-09-25 03:49:2215-16赛季CBA联赛之广东
日期:2018-09-25 04:09:12
3 [报告]
发表于 2016-03-30 16:50 |只看该作者
本帖最后由 _nosay 于 2016-03-30 17:38 编辑
  1. int fun1(int n)
  2. {
  3.         long base, here;

  4.         //printf("0x%x\n", (&n)[-1]);

  5. __asm__(
  6.         "r_base = .\n\t"
  7.         "r_here:movl r_base, %0\n\t"
  8.         "movl r_here, %1\n\t"
  9.         :"=a"((long)base), "=b"((long)here)
  10.         :"a"(0), "b"(0)
  11.         :
  12.         );

  13.         printf("0x%x, 0x%x\n", (unsigned int)base, (unsigned int)here);

  14.         return 0;
  15. }
复制代码
base值与here值打印结果一样,看来是紧接着的代码实际加载到内存的位置,那为什么fun1()、fun2()、fun3()相隔的那么远,而且还很有规律?
=在汇编里面用于定义变量,“r_base = .”与“r_base:”等效,可以说明汇编里面的标号也是变量吗?

论坛徽章:
20
程序设计版块每日发帖之星
日期:2015-08-17 06:20:00程序设计版块每日发帖之星
日期:2016-07-16 06:20:00程序设计版块每日发帖之星
日期:2016-07-18 06:20:00每日论坛发贴之星
日期:2016-07-18 06:20:00黑曼巴
日期:2016-12-26 16:00:3215-16赛季CBA联赛之江苏
日期:2017-06-26 11:05:5615-16赛季CBA联赛之上海
日期:2017-07-21 18:12:5015-16赛季CBA联赛之青岛
日期:2017-09-04 17:32:0515-16赛季CBA联赛之吉林
日期:2018-03-26 10:02:16程序设计版块每日发帖之星
日期:2016-07-15 06:20:0015-16赛季CBA联赛之江苏
日期:2016-07-07 18:37:512015亚冠之萨济拖拉机
日期:2015-08-17 12:21:08
4 [报告]
发表于 2016-03-31 10:28 |只看该作者
.是汇编过程中的概念,可以理解为当前code section的相对偏移。
这些符号相当于自动加入了一些label:,是编译过程中的常量。
  1. [test]$ cat test.c
  2. void f()
  3. {
  4.         asm("tmp1=.; mov tmp1, %rax");
  5.         asm("tmp2=.; mov tmp2, %rbx");
  6.         asm("tmp3=.; mov tmp3, %rcx; tmp3=.; mov tmp3, %rdx;");
  7. }
  8. [test]$ make test.o
  9. cc    -c -o test.o test.c
  10. [test]$ nm test.o
  11. 0000000000000000 T f
  12. 0000000000000004 t tmp1
  13. 000000000000000c t tmp2
  14. 000000000000001c t tmp3
  15. [test]$ objdump -d test.o

  16. test.o:     file format elf64-x86-64

  17. Disassembly of section .text:

  18. 0000000000000000 <f>:
  19.    0:        55                           push   %rbp
  20.    1:        48 89 e5                     mov    %rsp,%rbp

  21. 0000000000000004 <tmp1>:
  22.    4:        48 8b 04 25 00 00 00         mov    0x0,%rax
  23.    b:        00

  24. 000000000000000c <tmp2>:
  25.    c:        48 8b 1c 25 00 00 00         mov    0x0,%rbx
  26.   13:        00
  27.   14:        48 8b 0c 25 00 00 00         mov    0x0,%rcx
  28.   1b:        00

  29. 000000000000001c <tmp3>:
  30.   1c:        48 8b 14 25 00 00 00         mov    0x0,%rdx
  31.   23:        00
  32.   24:        c9                           leaveq
  33.   25:        c3                           retq  
复制代码

论坛徽章:
20
程序设计版块每日发帖之星
日期:2015-08-17 06:20:00程序设计版块每日发帖之星
日期:2016-07-16 06:20:00程序设计版块每日发帖之星
日期:2016-07-18 06:20:00每日论坛发贴之星
日期:2016-07-18 06:20:00黑曼巴
日期:2016-12-26 16:00:3215-16赛季CBA联赛之江苏
日期:2017-06-26 11:05:5615-16赛季CBA联赛之上海
日期:2017-07-21 18:12:5015-16赛季CBA联赛之青岛
日期:2017-09-04 17:32:0515-16赛季CBA联赛之吉林
日期:2018-03-26 10:02:16程序设计版块每日发帖之星
日期:2016-07-15 06:20:0015-16赛季CBA联赛之江苏
日期:2016-07-07 18:37:512015亚冠之萨济拖拉机
日期:2015-08-17 12:21:08
5 [报告]
发表于 2016-03-31 10:30 |只看该作者
本帖最后由 nswcfd 于 2016-03-31 15:03 编辑

0x48...是link之后的结果(即把相对偏移转换为绝对地址) 《==========【更新】这个解释是错误的,是指令本身。

论坛徽章:
20
程序设计版块每日发帖之星
日期:2015-08-17 06:20:00程序设计版块每日发帖之星
日期:2016-07-16 06:20:00程序设计版块每日发帖之星
日期:2016-07-18 06:20:00每日论坛发贴之星
日期:2016-07-18 06:20:00黑曼巴
日期:2016-12-26 16:00:3215-16赛季CBA联赛之江苏
日期:2017-06-26 11:05:5615-16赛季CBA联赛之上海
日期:2017-07-21 18:12:5015-16赛季CBA联赛之青岛
日期:2017-09-04 17:32:0515-16赛季CBA联赛之吉林
日期:2018-03-26 10:02:16程序设计版块每日发帖之星
日期:2016-07-15 06:20:0015-16赛季CBA联赛之江苏
日期:2016-07-07 18:37:512015亚冠之萨济拖拉机
日期:2015-08-17 12:21:08
6 [报告]
发表于 2016-03-31 10:48 |只看该作者
包含ld结果的例子。
  1. [test]$ cat test.c
  2. void f1()
  3. {
  4.   asm("tmp1=.; mov tmp1, %rax");
  5.   asm("tmp2=.; mov tmp2, %rbx");
  6.   asm("tmp3=.; mov tmp3, %rcx; tmp3=.; mov tmp3, %rdx;");
  7. }
  8. void f2()
  9. {
  10.   asm("myentry=.; nop; nop; mybase=.; movl $0xabcd, myentry-mybase");
  11. }
  12. int main()
  13. {
  14. }
  15. [test]$ make test.o test
  16. cc    -c -o test.o test.c
  17. cc   test.o   -o test
  18. [test]$ objdump -d test.o
  19. 0000000000000000 <f1>:
  20.    0: 55                    push   %rbp
  21.    1: 48 89 e5              mov    %rsp,%rbp
  22. 0000000000000004 <tmp1>:
  23.    4: 48 8b 04 25 00 00 00  mov    0x0,%rax
  24.    b: 00
  25. 000000000000000c <tmp2>:
  26.    c: 48 8b 1c 25 00 00 00  mov    0x0,%rbx
  27.   13: 00
  28.   14: 48 8b 0c 25 00 00 00  mov    0x0,%rcx
  29.   1b: 00
  30. 000000000000001c <tmp3>:
  31.   1c: 48 8b 14 25 00 00 00  mov    0x0,%rdx
  32.   23: 00
  33.   24: c9                    leaveq
  34.   25: c3                    retq   

  35. 0000000000000026 <f2>:
  36.   26: 55                    push   %rbp
  37.   27: 48 89 e5              mov    %rsp,%rbp
  38. 000000000000002a <myentry>:
  39.   2a: 90                    nop   
  40.   2b: 90                    nop   
  41. 000000000000002c <mybase>:
  42.   2c: c7 04 25 fe ff ff ff  movl   $0xabcd,0xfffffffffffffffe
  43.   33: cd ab 00 00
  44.   37: c9                    leaveq
  45.   38: c3                    retq   
  46. 0000000000000039 <main>:
  47.   39: 55                    push   %rbp
  48.   3a: 48 89 e5              mov    %rsp,%rbp
  49.   3d: c9                    leaveq
  50.   3e: c3                    retq   
  51. [test]$ objdump -d test
  52. 0000000000400448 <f1>:
  53.   400448: 55                    push   %rbp
  54.   400449: 48 89 e5              mov    %rsp,%rbp
  55. 000000000040044c <tmp1>:
  56.   40044c: 48 8b 04 25 4c 04 40  mov    0x40044c,%rax
  57.   400453: 00
  58. 0000000000400454 <tmp2>:
  59.   400454: 48 8b 1c 25 54 04 40  mov    0x400454,%rbx
  60.   40045b: 00
  61.   40045c: 48 8b 0c 25 5c 04 40  mov    0x40045c,%rcx
  62.   400463: 00
  63. 0000000000400464 <tmp3>:
  64.   400464: 48 8b 14 25 64 04 40  mov    0x400464,%rdx
  65.   40046b: 00
  66.   40046c: c9                    leaveq
  67.   40046d: c3                    retq   

  68. 000000000040046e <f2>:
  69.   40046e: 55                    push   %rbp
  70.   40046f: 48 89 e5              mov    %rsp,%rbp
  71. 0000000000400472 <myentry>:
  72.   400472: 90                    nop   
  73.   400473: 90                    nop   
  74. 0000000000400474 <mybase>:
  75.   400474: c7 04 25 fe ff ff ff  movl   $0xabcd,0xfffffffffffffffe
  76.   40047b: cd ab 00 00
  77.   40047f: c9                    leaveq
  78.   400480: c3                    retq   
复制代码

论坛徽章:
13
15-16赛季CBA联赛之八一
日期:2016-07-08 21:00:1415-16赛季CBA联赛之同曦
日期:2017-02-15 14:26:1515-16赛季CBA联赛之佛山
日期:2017-02-20 14:19:2615-16赛季CBA联赛之青岛
日期:2017-05-07 16:49:1115-16赛季CBA联赛之广夏
日期:2017-07-30 09:13:1215-16赛季CBA联赛之广东
日期:2018-07-05 22:34:3615-16赛季CBA联赛之江苏
日期:2018-09-03 12:10:2115-16赛季CBA联赛之上海
日期:2018-09-25 03:49:2215-16赛季CBA联赛之广东
日期:2018-09-25 04:09:12
7 [报告]
发表于 2016-03-31 13:35 |只看该作者
回复 6# nswcfd

我是直接编译成可执行文件的,所以已经链接过了,但是,fun1的地址是0x8048410,fun1()中的r_base值打印出来是0x48423a1。

fun1()代码(原始):
  1. int fun1(int n)
  2. {
  3.         long base, here;

  4.         //printf("0x%x\n", (&n)[-1]);

  5. __asm__(
  6.         "r_base = .\n\t"
  7.         "r_here:movl r_base, %0\n\t"
  8.         "movl r_here, %1\n\t"
  9.         :"=a"((long)base), "=b"((long)here)
  10.         :"a"(0), "b"(0)
  11.         :
  12.         );

  13.         printf("0x%x, 0x%x\n", (unsigned int)base, (unsigned int)here);

  14.         return 0;
  15. }
复制代码
fun1()代码(objdump -d):
  1. 08048410 <fun1>:
  2. 8048410:       55                      push   %ebp
  3. 8048411:       89 e5                   mov    %esp,%ebp
  4. 8048413:       53                      push   %ebx
  5. 8048414:       83 ec 24                sub    $0x24,%esp
  6. 8048417:       b8 00 00 00 00          mov    $0x0,%eax
  7. 804841c:       ba 00 00 00 00          mov    $0x0,%edx
  8. 8048421:       89 d3                   mov    %edx,%ebx

  9. 08048423 <r_here>:
  10. 8048423:       a1 23 84 04 08          mov    0x8048423,%eax
  11. 8048428:       8b 1d 23 84 04 08       mov    0x8048423,%ebx
  12. 804842e:       89 da                   mov    %ebx,%edx
  13. 8048430:       89 45 f0                mov    %eax,-0x10(%ebp)
  14. 8048433:       89 55 f4                mov    %edx,-0xc(%ebp)
  15. 8048436:       8b 55 f4                mov    -0xc(%ebp),%edx
  16. 8048439:       8b 45 f0                mov    -0x10(%ebp),%eax
  17. 804843c:       89 54 24 08             mov    %edx,0x8(%esp)
  18. 8048440:       89 44 24 04             mov    %eax,0x4(%esp)
  19. 8048444:       c7 04 24 88 85 04 08    movl   $0x8048588,(%esp)
  20. 804844b:       e8 a0 fe ff ff          call   80482f0 <printf@plt>
  21. 8048450:       b8 00 00 00 00          mov    $0x0,%eax
  22. 8048455:       83 c4 24                add    $0x24,%esp
  23. 8048458:       5b                      pop    %ebx
  24. 8048459:       5d                      pop    %ebp
  25. 804845a:       c3                      ret
复制代码
可执行程序打印:
0x48423a1, 0x48423a1  // fun1()中打印的r_base、r_here值
0x48466a1
0x48493a1

论坛徽章:
13
15-16赛季CBA联赛之八一
日期:2016-07-08 21:00:1415-16赛季CBA联赛之同曦
日期:2017-02-15 14:26:1515-16赛季CBA联赛之佛山
日期:2017-02-20 14:19:2615-16赛季CBA联赛之青岛
日期:2017-05-07 16:49:1115-16赛季CBA联赛之广夏
日期:2017-07-30 09:13:1215-16赛季CBA联赛之广东
日期:2018-07-05 22:34:3615-16赛季CBA联赛之江苏
日期:2018-09-03 12:10:2115-16赛季CBA联赛之上海
日期:2018-09-25 03:49:2215-16赛季CBA联赛之广东
日期:2018-09-25 04:09:12
8 [报告]
发表于 2016-03-31 13:48 |只看该作者
本帖最后由 _nosay 于 2016-03-31 13:48 编辑

回复 6# nswcfd

不过。。

上面的第11、12行:
  1. 8048423:       a1 23 84 04 08          mov    0x8048423,%eax
  2. 8048428:       8b 1d 23 84 04 08       mov    0x8048423,%ebx
复制代码
对应的c代码是:
  1.         "r_here:movl r_base, %0\n\t"
  2.         "movl r_here, %1\n\t"
复制代码
证明了你说的是对的,r_base值正是当前这条指令的绝对地址0x8048423,为什么printf()打印出来的变成0x48423a1了?难道“movl r_base, %0”是将0x8048423处的内容放到base变量了吗?

论坛徽章:
13
15-16赛季CBA联赛之八一
日期:2016-07-08 21:00:1415-16赛季CBA联赛之同曦
日期:2017-02-15 14:26:1515-16赛季CBA联赛之佛山
日期:2017-02-20 14:19:2615-16赛季CBA联赛之青岛
日期:2017-05-07 16:49:1115-16赛季CBA联赛之广夏
日期:2017-07-30 09:13:1215-16赛季CBA联赛之广东
日期:2018-07-05 22:34:3615-16赛季CBA联赛之江苏
日期:2018-09-03 12:10:2115-16赛季CBA联赛之上海
日期:2018-09-25 03:49:2215-16赛季CBA联赛之广东
日期:2018-09-25 04:09:12
9 [报告]
发表于 2016-03-31 13:57 |只看该作者
回复 6# nswcfd

没加$,
  1.         "r_here:movl $r_base, %0\n\t"
  2.         "movl $r_here, %1\n\t"
复制代码
[120] $ ./a.out
0x8048423, 0x8048423
0x48465a1
0x48492a1

好,一切悬疑都解开了 。。

论坛徽章:
20
程序设计版块每日发帖之星
日期:2015-08-17 06:20:00程序设计版块每日发帖之星
日期:2016-07-16 06:20:00程序设计版块每日发帖之星
日期:2016-07-18 06:20:00每日论坛发贴之星
日期:2016-07-18 06:20:00黑曼巴
日期:2016-12-26 16:00:3215-16赛季CBA联赛之江苏
日期:2017-06-26 11:05:5615-16赛季CBA联赛之上海
日期:2017-07-21 18:12:5015-16赛季CBA联赛之青岛
日期:2017-09-04 17:32:0515-16赛季CBA联赛之吉林
日期:2018-03-26 10:02:16程序设计版块每日发帖之星
日期:2016-07-15 06:20:0015-16赛季CBA联赛之江苏
日期:2016-07-07 18:37:512015亚冠之萨济拖拉机
日期:2015-08-17 12:21:08
10 [报告]
发表于 2016-03-31 14:59 |只看该作者
是的,对一个label:而言,$label代表的label的地址,label代表的是label执行的内容,也就是代码段里的指令。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP