# #assembly #clang #llvm #x86-64 #llvm-ir
#собрание #лязг #llvm #x86-64 #llvm-ик
Вопрос:
У меня есть следующий ИК-код LLVM, в котором я пытаюсь выполнить некоторые инструкции по сборке, в которых я использую регистры, созданные мной самим.
;[ASM] mov dword ptr [RBP-0x4], 0xa ;[Def] [(i64 %RBP i64 0xfffffffffffffffc)] := i32 0xa %T_0_14 = add i64 %RBP , -4 %T_0_17 = zext i32 10 to i64 %T_0_18 = inttoptr i64 %T_0_14 to i64* store i64 %T_0_17 , i64* %T_0_18 ;------------------------------------ ;[ASM] mov EDX, dword ptr [RBP-0x4] ;[Def] i64 %RDX := zext:I64([(i64 %RBP i64 0xfffffffffffffffc)]:I32) %T_0_28 = add i64 %RBP , -4 %T_0_29 = inttoptr i64 %T_0_28 to i64* %T_0_27 = load i64 , i64* %T_0_29 store i64 %T_0_27 , i64* @RDX %ans = load i64, i64* @RDX ret i64 %ans
Из приведенного выше кода я ожидаю @RDX
, что он будет содержать значение 0xa
или 10
, однако, когда я запускаю этот код, он выводится 0
. В первой части кода я преобразую %RBP-4
в указатель, который есть %T_0_18
, и сохраняю 0x10
его там. Во второй части я загружаю значение с этого адреса @RDX
, однако на этот раз это делается с использованием локальной переменной %T_0_27
, которая должна быть такой же, как %T_0_18
. В чем может быть проблема?
Правка 1: регистры определены, как показано ниже:
%struct.State = type { %struct.FLAGS, %struct.GPR } %struct.FLAGS = type { i64, %struct.Flag, i64, %struct.Flag, i64, %struct.Flag, i64, %struct.Flag, i64, %struct.Flag, i64, %struct.Flag } %struct.Reg = type { i64 } %struct.Flag = type { i1 } %struct.GPR = type { i64, %struct.Reg, i64, %struct.Reg, i64, %struct.Reg, i64, %struct.Reg, i64, %struct.Reg, i64, %struct.Reg, i64, %struct.Reg, i64, %struct.Reg, i64, %struct.Reg, i64, %struct.Reg, i64, %struct.Reg, i64, %struct.Reg, i64, %struct.Reg, i64, %struct.Reg, i64, %struct.Reg, i64, %struct.Reg, i64, %struct.Reg } @reg_state = global %struct.State zeroinitializer %union.anon = type { i64 } @shadow_stack = internal global [1048576 x i64] zeroinitializer @RAX = private alias i64, getelementptr inbounds (%struct.State, %struct.State* @reg_state, i32 0, i32 1, i32 1, i32 0) @RBX = private alias i64, getelementptr inbounds (%struct.State, %struct.State* @reg_state, i32 0, i32 1, i32 3, i32 0) @RCX = private alias i64, getelementptr inbounds (%struct.State, %struct.State* @reg_state, i32 0, i32 1, i32 5, i32 0) @RDX = private alias i64, getelementptr inbounds (%struct.State, %struct.State* @reg_state, i32 0, i32 1, i32 7, i32 0) ...
Правка 2: Я также определил переменные регистра локально:
define i64 @func_1020() { bb_4128: ; lt;labelgt;:4128: call void @initStack() %RAX = load i64, i64* @RAX %RBX = load i64, i64* @RBX %RCX = load i64, i64* @RCX %RDX = load i64, i64* @RDX %RSI = load i64, i64* @RSI %RDI = load i64, i64* @RDI %RSP = load i64, i64* @RSP %RBP = load i64, i64* @RBP %R8 = load i64, i64* @R8 %R9 = load i64, i64* @R9 ...
Комментарии:
1. Некоторые значения, которые вы используете, имеют
%
префикс, что означает, что они являются локальными.%RBX
И@RBX
— это разные вещи. Вы уверены, что ваш код верен?2. @arrowd Я отредактировал сообщение. Я тоже объявил регистры локально.
3. Попробуйте перешагнуть через свой код с
lli
помощью отладчика. И не публикуйте скриншоты кода.4. @arrowd Спасибо вам за ваши отзывы. Можете ли вы предоставить мне какие-либо ресурсы о том, как отлаживать с помощью lli? Я пытался найти отладчики для llvm раньше, но вроде как заблудился.
5. @arrowd могу ли я отладить свой код без создания двоичного файла из моего файла .ll?