У меня есть код на C:
int64_t sample_max(int64_t *beg, int64_t len) {
if (len == 0) {
return 0;
}
int64_t max = 0x8000000000000000;
int64_t *end = beg + len;
while (beg < end) {
if (*beg > max) {
max = *beg;
}
beg++;
}
return max;
}
и выполните его лязгом:
clang -S -target x86_64-unknown-none -masm=intel -mno-red-zone -mstackrealign -mllvm -inline-threshold=1000 -fno-asynchronous-unwind-tables -fno-exceptions -fno-rtti -O3 -fno-builtin -ffast-math -mavx2 lib/sample.c -o lib/sample_avx2.s
и я обнаружил, что clang / llvm соответствует глобальным локальным переменным «max = 0x8000000000000000»:
vpbroadcastq ymm0, qword ptr [rip + .LCPI1_0]
vmovdqa ymm3, ymm0
vmovdqa ymm2, ymm0
vmovdqa ymm1, ymm0
....
.LCPI1_0:
.quad -9223372036854775808 # 0x8000000000000000
.section .rodata,"a",@progbits
.align 32
Как предотвратить компиляцию локальных переменных clang / llvm в глобальные? Можем ли мы скомпилировать 0x8000000000000000 с немедленными значениями?
Спасибо.
Локальные переменные не являются глобальными. Компилятор использует для них регистры. Он хранит 0x8000000000000000 с фактически статической продолжительностью хранения. 0x8000000000000000 - это константа, а не переменная. Компилятор может реализовать это по своему усмотрению. Что вас беспокоит по поводу того, как он хранится - почему вас это волнует, как это влияет на вас?
@MarcGlisse @Eric Postpischil Я хочу преобразовать эти asm в go-asm с помощью c2goasm
. И встречаю вопрос github.com/minio/c2goasm/issues/8
@EricPostpischil Я хочу преобразовать эти asm в go-asm с помощью c2goasm. И я столкнулся с проблемой github.com/minio/c2goasm/issues/8
Скомпилируйте с использованием флага -Os. Это остановит создание глобальных таблиц переходов. Протестировано с помощью clang 3.8
Зачем тебе это нужно? А какой именно asm вы ожидаете? Какой-то movabsq, за которым следует переход в регистр XMM (возможно, через память в зависимости от точной цели) и, наконец, трансляция?