Этот код может работать:
.text
.global main
main:
add $-8, %rsp # Stack is misaligned by 8 after call to main
# Subtract 8 to align it on 16-byte boundary
xor %rax, %rax # RAX = 0 since no vector registers used for calling printf
# This is important for functions that take variable
# number of arguments
movq $formatString, %rdi # First parameter (format) in RDI
movq $10, %rsi # second parameter in RSI not RDX
call printf
add $8, %rsp # Restore stack to proper state
ret
.data
formatString:
.string "%ld\n" # If printing longs use %ld
Вместо add $-8, %rsp
и add $8, %rsp
для выравнивания стека можно использовать все, что настраивает стек на 8 байт. push %rbx
и pop %rbx
тоже сработали бы.
В качестве альтернативы можно заменить:
movq $formatString, %rdi # First parameter (format) in RDI
С:
leaq formatString(%rip), %rdi
Последний использует RIP-относительной адресации, а не абсолютным.
Дополнительную информацию о 64-разрядной системе Linux V ABI можно найти в этом document.
Вы знаете, что можете «mov $ 10,% edx', правильно? Теперь это всего лишь дубликат многих забытых до нуля-rax, прежде чем вызывать вопрос функции var-args. Я связал один из них как возможный дубликат по вашему предыдущему вопросу. 'push'ing dummy register - полезный способ выровнять стек перед' вызовом', в функции, которая иначе не требует резервирования какого-либо пространства. Также прочитайте документы ABI. Второй аргумент не входит в '% rdx'. –
Возможный дубликат [Попытка добавления двух ints, в x86, однако, когда я добавляю, я получаю мусор вместо значения. что я делаю неправильно?] (http://stackoverflow.com/questions/28706080/trying-to-add-two-ints-in-x86-however-when-i-add-i-get-garbage-instead- of-a-val) –
Стек также должен быть выровнен по 16-байтовой границе, _RAX_ должен быть равен нулю в этом случае, потому что вы не используете векторные регистры. –