Ассемблер GNU (который использует gcc) не использует синтаксис NASM.Он скорее использует вариант синтаксиса MASM от Microsoft, где для разыменования переменной не нужны скобки.Поскольку вы не хотите загружать значение переменной c
, а скорее ее адрес, вам нужно ключевое слово offset
:
mov ecx, offset c
Я настоятельно рекомендую вам избегать встроенной сборки в максимально возможной степени.для обучения сборке.Использование встроенной сборки в gcc требует хороших знаний о том, как именно все это работает, и написание случайных инструкций обычно приводит к неправильному коду.Даже ваш простой код уже в корне сломан и не будет работать, если он будет более сложным, чем этот (поэтому у компилятора была возможность попытаться использовать регистры, которые вы перезаписали, не сообщая).
Вместо этого поместите свою сборкув отдельном файле и свяжите его. Это позволяет обойти все проблемы, связанные с встроенной сборкой, и позволяет использовать NASM так, как вы этого хотите.Например, попробуйте что-то вроде этого:
main.c
char c[] = "abcd";
/* the function you define in print_c.asm */
extern void print_c();
int main() {
print_c(); /* call your assembly function */
}
print_c.asm
; pull in c defined in main.c
extern c
section .text
global print_c
print_c:
; write c to stdout
mov eax, 4
mov ebx, 1
mov ecx, c
mov edx, 5
int 0x80
; exit program
mov eax, 1
int 0x80
Затем соберите, скомпилируйте и свяжите с:
nasm -felf print_c.asm
cc -m32 -o print_c print_c.o main.c