Является ли это экзаменационным экзаменом или C-структурой реального мира?
В реальном мире он может быть дополнен, чтобы выровнять его членов, так что .b
может быть затем 4 или 8 (или больше, зависит от компиляции установки времени для заполнения), не 2.
При выполнении C < - > asm для реального, не забудьте использовать какой-то «padding/packing» прагма или компилятор времени для компиляции всегда в одну и ту же структуру структуры в C-файлах (первый шаг).
Тогда, возможно, вы можете наложить/выровнять вручную, например, я бы поставил «a» как последний и «c» и «d» в начале. Таким образом, порядок в памяти будет «c, d, b, a» (который я нашел бы «достаточно», выровненным даже для цели 64b в «упакованном» режиме, результирующие смещения будут [0, 8, 16, 20]
, а размер будет 22
байт) (править : и я добавлю еще word
в конец, чтобы разместить его до размера 24B, если бы я знал, что буду использовать многие из них в массиве).
И наконец, что такое c
и d
в памяти -> указатели. При использовании слова «nasm» я ощущаю целевую платформу x86, а «uint32_t» чувствует, что это будет не реальный режим 16b, поэтому они либо 32, либо 64 бита (в зависимости от вашей целевой платформы). 32 бита - 4 байта, 64 бита - 8 байтов.
Кстати, вы всегда можете написать короткий источник C, осуществляющий доступ к структуре, и проверить выход компилятора.
Например я это в http://godbolt.org/:
#include <cstdint>
struct struct1 {
uint16_t a;
uint32_t b;
char * c;
void * d;
};
std::size_t testFunction(struct1 *in) {
std::size_t r = in->a;
r += in->b;
r += uintptr_t(in->c);
r += uintptr_t(in->d);
return r;
}
И получил на это (лязг 3.9.0 -O3 -m32 -std = C++ 11):
testFunction(struct1*): # @testFunction(struct1*)
mov ecx, dword ptr [esp + 4] ; ecx = "in" pointer
movzx eax, word ptr [ecx] ; +0 for "a"
add eax, dword ptr [ecx + 4] ; +4 for "b"
add eax, dword ptr [ecx + 8] ; +8 for "c"
add eax, dword ptr [ecx + 12] ; +12 for "d"
ret ; size of struct is 16B
И 64b Цель:
testFunction(struct1*): # @testFunction(struct1*)
mov rax, qword ptr [rdi]
movzx ecx, ax
shr rax, 32
add rax, rcx
add rax, qword ptr [rdi + 8]
add rax, qword ptr [rdi + 16]
ret
Смещения теперь 0, 4, 8 и 16, а размер 24B.
и 64b мишени с добавлением "-fpack-структуры = 1":
testFunction(struct1*): # @testFunction(struct1*)
movzx ecx, word ptr [rdi]
mov eax, dword ptr [rdi + 2]
add rax, rcx
add rax, qword ptr [rdi + 6]
add rax, qword ptr [rdi + 14]
ret
Смещения равны 0, 2, 6 и 14, и размер 22B (и производительность пострадает от выровненным доступа к членам b
, c
и d
).
Так, например, для 0, 4, 8, 16 случая (64b выровнены) Ваш NASM структура должна быть:
struc struct1
.a resd 1
.b resd 1
.c resq 1
.d resq 1
endstruc
Из ваших дальнейших комментариев ... Я думаю, что вы, возможно, своего рода пропустите, что такое «структура» в сборке.Это трюк, это просто другой способ указания смещений адресов. Приведенный выше пример можно назвать также:
struc struct1
.a resw 1
resw 1 ; padding to make "b" start at offset 4
.b resd 1
.c resq 1
.d resq 1
endstruc
Теперь у вас есть «resw» для «a». Для ASM это не имеет значения, так как для кода важно только значение символов .a
и .b
, и эти значения являются 0
и 4
в обоих примерах. Неважно, как вы зарезервируете пространство внутри определения struc
, оно не влияет на результат, если вы укажете правильное количество байтов для конкретной «переменной» + его заполнения.
'.c <размер указателя>', '.d' (который будет зависеть от архитектуры). –