在 masm x64 上打印具有多个参数
Printf on masm x64 with multiple parameters
我需要在asm(在Windows上(中创建一个复制以下行为的函数:
_int64 q(_int64 a, _int64 b, _int64 c, _int64 d, _int64 e) {
_int64 sum = a + b + c + d + e;
printf("a = %I64d b = %I64d c = %I64d d = %I64d e = %I64d sum = %I64dn", a, b, c, d, e, sum);
return sum;
}
我知道我需要为 printf 分配阴影空间,并且我需要在堆栈中存储一些参数,因为只有前 4 个参数在寄存器中(rcx、rdx、r8 和 r9(
我的问题来自字符串格式和堆栈管理。 到目前为止,我的代码如下所示:
.data
string1 dq 'a = %I64d b = %I64d c = %I64d d = %I64d e = %I64d sum = %I64d', 10, 0 ; The printf format, "n",'0'
.code
public q ;a in rcx, b in rdx, c in r8, d in r9, e in stack
q: push rbp
mov rbp, rsp
sub rsp, 32 ;allocating shadow space for printf
;for calling printf, we need to have [string] in rcx,
;a in rdx, b in r8, c in r9, d in stack1, e in stack2, and sum in stack3
add rax, rcx ;first make the sum
add rax, rdx
add rax, r8
add rax, r9
mov rbx, [rbp + 8] ;getting e from the stack
add rax, rbx ;final add, in rax now is sum
push rax ;changing parameters in registers (last 3 in stack)
push rbx
push r9
mov r9, r8 ;c in r9
mov r8, rdx ;b in r8
mov rdx, rcx ;a in rdx
lea rcx, [string] ;string in rcx
call printf
mov rsp, rbp ;back to previous pointer
pop rbp ;release resources
ret 0
end
目前它不编译,带有
错误 A2084:常量值太大
我不知道我是否需要更改格式或将其拆分为 2,在这种情况下,我需要在堆栈中存储一些其他参数,然后我不太确定如何进行......
如果该错误与字符串一起,请使用db
而不是dq
:您不希望将10, 0
元素填充到 qwords 中,即使它确实像 NASM 那样接受引用的部分作为字符串。
我认为 MASM 允许引用常量用于db
,因此应该让它组装。
然后我们在运行时还有多个其他错误:
此外,如果要在推送 3 个寄存器后恢复它们,则需要sub rsp, 32
保留影子空间。 否则,这24个字节是被调用函数(printf
(看到的阴影空间的底部。
但这毫无意义,因为您不会在通话后恢复它们。 所以你违反了调用约定,破坏了rbx
;看起来你在调用后没有对它们做任何事情,所以只需使用调用破坏的reg,或者更好地计算正确的arg传递寄存器中的值。
相关文章:
- C++ cout 不打印所有参数
- 在 masm x64 上打印具有多个参数
- 打印带有指针的参数和环境
- 在C++中使用getopt时打印默认参数
- 使用宏定义打印格式参数
- 为什么我不能提供一个字符串参数来打印 ncurses?
- 作为参数传递的打印功能指针导致屏幕上打印"1"
- 如何打印作为参数传递的函数的名称
- 如何使用递归按从 1 到 n 的升序打印数字,其中 n 在该函数的参数中给出
- 如果我不打印函数参数的值,则将其转换为等于零
- 为什么我的代码两次打印相同的命令行参数
- C++ 命令行参数不从文本文件中打印出值
- 我需要创建一个函数在用户下打印"=",但由于变量是使用 main() 声明的,因此函数看不到参数
- GDB有没有办法在不省略模板参数的情况下打印类型
- 如何打印带有参数的变量的名称
- 如何对函数参数的类型铸件进行G 打印警告
- 如何在编译时漂亮地打印模板参数的名称
- 如何使用可变模板打印出函数的参数
- 如何使用带2个参数的void函数多次打印消息
- 将 char* 字符串参数打印到 UnicodeString 对象中