LINUX.ORG.RU

История изменений

Исправление hateyoufeel, (текущая версия) :

0000000000001100 <tmp_swap>:
    1100:       8b 07                   mov    (%rdi),%eax
    1102:       8b 0e                   mov    (%rsi),%ecx
    1104:       89 0f                   mov    %ecx,(%rdi)
    1106:       89 06                   mov    %eax,(%rsi)
    1108:       c3                      ret
    1109:       0f 1f 80 00 00 00 00    nopl   0x0(%rax)

0000000000001110 <xor_swap>:
    1110:       8b 07                   mov    (%rdi),%eax
    1112:       33 06                   xor    (%rsi),%eax
    1114:       89 07                   mov    %eax,(%rdi)
    1116:       33 06                   xor    (%rsi),%eax
    1118:       89 06                   mov    %eax,(%rsi)
    111a:       31 07                   xor    %eax,(%rdi)
    111c:       c3                      ret
    111d:       0f 1f 00                nopl   (%rax)

0000000000001120 <minus_swap>:
    1120:       8b 06                   mov    (%rsi),%eax
    1122:       03 07                   add    (%rdi),%eax
    1124:       89 07                   mov    %eax,(%rdi)
    1126:       2b 06                   sub    (%rsi),%eax
    1128:       89 06                   mov    %eax,(%rsi)
    112a:       29 07                   sub    %eax,(%rdi)
    112c:       c3                      ret

Как видишь, нет. Сборка:

$ cat lib.c
void tmp_swap(int *a, int *b) {
  int tmp = *a;
  *a = *b;
  *b = tmp;
}

void xor_swap(int *a, int *b) {
  *a ^= *b;
  *b ^= *a;
  *a ^= *b;
}

void minus_swap(int *a, int *b) {
  *a = *a + *b;
  *b = *a - *b;
  *a = *a - *b;
}

$ cat lib.h
#pragma once

extern void tmp_swap(int *a, int *b);
extern void xor_swap(int *a, int *b);
extern void minus_swap(int *a, int *b);

$ cat main.c
#include "lib.h"

int main(void) {
  int a = 1, b = 2;

  int iters = 1024 * 1024 * 1024;
  while(iters--)
    minus_swap(&a, &b);

  return 0;
}

$ clang lib.c -O2 -shared -o libswap.so
$ clang main.c -lswap -L. -O2 -o main
$ export LD_LIBRARY_PATH="."
 

Компилятор не может выкинуть код твоей функции или заинлайнить его, если он его не видит (:

А теперь ВНИМАНИЕ вопрос: если сишечка – низкоуровневый язык, куда делась лишняя переменная-то? Что это за выкрутасы такие?

Исправление hateyoufeel, :

0000000000001100 <tmp_swap>:
    1100:       8b 07                   mov    (%rdi),%eax
    1102:       8b 0e                   mov    (%rsi),%ecx
    1104:       89 0f                   mov    %ecx,(%rdi)
    1106:       89 06                   mov    %eax,(%rsi)
    1108:       c3                      ret
    1109:       0f 1f 80 00 00 00 00    nopl   0x0(%rax)

0000000000001110 <xor_swap>:
    1110:       8b 07                   mov    (%rdi),%eax
    1112:       33 06                   xor    (%rsi),%eax
    1114:       89 07                   mov    %eax,(%rdi)
    1116:       33 06                   xor    (%rsi),%eax
    1118:       89 06                   mov    %eax,(%rsi)
    111a:       31 07                   xor    %eax,(%rdi)
    111c:       c3                      ret
    111d:       0f 1f 00                nopl   (%rax)

0000000000001120 <minus_swap>:
    1120:       8b 06                   mov    (%rsi),%eax
    1122:       03 07                   add    (%rdi),%eax
    1124:       89 07                   mov    %eax,(%rdi)
    1126:       2b 06                   sub    (%rsi),%eax
    1128:       89 06                   mov    %eax,(%rsi)
    112a:       29 07                   sub    %eax,(%rdi)
    112c:       c3                      ret

Как видишь, нет. Сборка:

$ cat lib.c
void tmp_swap(int *a, int *b) {
  int tmp = *a;
  *a = *b;
  *b = tmp;
}

void xor_swap(int *a, int *b) {
  *a ^= *b;
  *b ^= *a;
  *a ^= *b;
}

void minus_swap(int *a, int *b) {
  *a = *a + *b;
  *b = *a - *b;
  *a = *a - *b;
}

$ cat lib.h
#pragma once

extern void tmp_swap(int *a, int *b);
extern void xor_swap(int *a, int *b);
extern void minus_swap(int *a, int *b);

$ cat main.c
#include "lib.h"

int main(void) {
  int a = 1, b = 2;

  int iters = 1024 * 1024 * 1024;
  while(iters--)
    minus_swap(&a, &b);

  return 0;
}

$ clang lib.c -O2 -shared -o libswap.so
$ clang main.c -lswap -L. -O2 -o main
$ export LD_LIBRARY_PATH="."
 

Компилятор не может выкинуть код твоей функции или заинлайнить его, если он его не видит (:

Исходная версия hateyoufeel, :

0000000000001100 <tmp_swap>:
    1100:       8b 07                   mov    (%rdi),%eax
    1102:       8b 0e                   mov    (%rsi),%ecx
    1104:       89 0f                   mov    %ecx,(%rdi)
    1106:       89 06                   mov    %eax,(%rsi)
    1108:       c3                      ret
    1109:       0f 1f 80 00 00 00 00    nopl   0x0(%rax)

0000000000001110 <xor_swap>:
    1110:       8b 07                   mov    (%rdi),%eax
    1112:       33 06                   xor    (%rsi),%eax
    1114:       89 07                   mov    %eax,(%rdi)
    1116:       33 06                   xor    (%rsi),%eax
    1118:       89 06                   mov    %eax,(%rsi)
    111a:       31 07                   xor    %eax,(%rdi)
    111c:       c3                      ret
    111d:       0f 1f 00                nopl   (%rax)

0000000000001120 <minus_swap>:
    1120:       8b 06                   mov    (%rsi),%eax
    1122:       03 07                   add    (%rdi),%eax
    1124:       89 07                   mov    %eax,(%rdi)
    1126:       2b 06                   sub    (%rsi),%eax
    1128:       89 06                   mov    %eax,(%rsi)
    112a:       29 07                   sub    %eax,(%rdi)
    112c:       c3                      ret

Как видишь, нет. Сборка:

$ cat lib.c
void tmp_swap(int *a, int *b) {
  int tmp = *a;
  *a = *b;
  *b = tmp;
}

void xor_swap(int *a, int *b) {
  *a ^= *b;
  *b ^= *a;
  *a ^= *b;
}

void minus_swap(int *a, int *b) {
  *a = *a + *b;
  *b = *a - *b;
  *a = *a - *b;
}

$ cat lib.h
#pragma once

extern void tmp_swap(int *a, int *b);
extern void xor_swap(int *a, int *b);
extern void minus_swap(int *a, int *b);

$ cat main.c
#include "lib.h"

int main(void) {
  int a = 1, b = 2;

  int iters = 1024 * 1024 * 1024;
  while(iters--)
    minus_swap(&a, &b);

  return 0;
}

$ clang lib.c -O2 -shared -o libswap.so
$ clang main.c -lswap -L. -O2 -o main
$ export LD_LIBRARY_PATH="."