Macros 为什么nasm打印字符而不是字符串?
具有以下特征:Macros 为什么nasm打印字符而不是字符串?,macros,printf,x86-64,nasm,Macros,Printf,X86 64,Nasm,具有以下特征: %macro print 2 push rbp mov rbp, rsp mov rdi, %1 mov esi, %2 call printf leave ret %endmacro section .data dat db "string %c", 0xa, 0x0 section .text extern printf global main main: print dat, "n" mov ra
%macro print 2
push rbp
mov rbp, rsp
mov rdi, %1
mov esi, %2
call printf
leave
ret
%endmacro
section .data
dat db "string %c", 0xa, 0x0
section .text
extern printf
global main
main:
print dat, "n"
mov rax, 60
syscall
它会很好用的
但是当我试着改变这个的时候
(在数据部分)
dat db“字符串%s”、0xa、0x0
和(在文本部分)
打印数据,“某物”
然后
如果字符串太长(5个或更多字符),但只有4个字节或更少,“only”错误:
命令终止
。如图所示,printf
只接受rsi
中的dword
(4字节)(c风格的第二个[任意]参数),而不是更大的类型,但为什么?(即使给定的字符串为4字节或更少,仍然命令终止
)。如何解决这个问题?movesi,“something”
将ASCII值放入寄存器,而不是指向内存中以0结尾的C字符串的指针<代码>%s仅接受指针;它怎么知道寄存器中的值应该是逐值字符而不是指针呢?我不知道nasm将双引号解释为文本ascii,但认为它是指向字符数组的指针(就像在c中一样)。那我就明白问题了@为了让它像C一样工作,NASM必须神奇地将字符串放在内存中的某个地方,这样您就可以得到指向它的指针。但它只是一个汇编程序,不是一个编译器;它不会神奇地为您将内容放入.rodata
部分(或者.data
?它甚至如何知道您是否想要只读)。也许这有助于理解为什么NASM这样做毫无意义section
和db
指令的存在是有原因的,字符串不是程序集中的第一类对象,它们是必须实现的。
p.s:18: warning: dword data exceeds bounds [-w+number-overflow]
p.s:5: ... from macro `print' defined here [-w+number-overflow]