所以我有这个Assembly程序,我试图在其中使用对printf的调用来输出一些数据,但它不会打印出我要打印的全部内容。
.section .data
output:
.asciz "The processor Vendor ID is ‘%s’\n"
.section .bss
.lcomm buffer, 64
.section .text
.globl _start
_start:
pushq %rbx
movq $0, %rax
cpuid
movq $buffer, %rsi
movq $output, %rdi
mov %ebx, 28(%rdi)
mov %ecx, 32(%rdi)
#mov %edx, 35(%rdi)
movq $0, %rax
call printf
movq $60, %rax
movq $0, %rdi
popq %rbx
syscall
但是,此版本绝对不打印任何内容。此版本:
.section .data
output:
.asciz "The processor Vendor ID is ‘%s’\n"
.section .bss
.lcomm buffer, 64
.section .text
.globl _start
_start:
pushq %rbx
movq $0, %rax
cpuid
movq $buffer, %rsi
movq $output, %rdi
mov %ebx, 27(%rdi)
mov %ecx, 31(%rdi)
#mov %edx, 35(%rdi)
movq $0, %rax
call printf
movq $60, %rax
movq $0, %rdi
popq %rbx
syscall
即使偏移量仅改变了一个,该版本也会打印出The processor Vendor ID is Genuntel
。如果包含注释行,则程序无论如何都不会打印任何内容(在第一个示例中,偏移量是错误的,但即使偏移量是36,也不会打印)。因此,我很好奇偏移如何影响偏移量,以便它不会在第一个偏移量上打印,而在第二个偏移量上打印。
请记住,这是一项学校任务,但是我已经尝试了好几天,但似乎无法正常工作。
答案 0 :(得分:1)
此代码似乎是为您设置的,用于将字符串字节存储到相对于RSI的buffer
中,因此格式字符串中的%s
转换将打印它。但是使用.data
中的字符串而不是应该放置只读数据的.rodata
中的字符串,是的,您可以在运行时覆盖格式字符串的字节。
覆盖\n
时,printf
不会刷新输出缓冲区,因为stdout
是行缓冲的。您以sys_exit
(直接系统调用)而不是call exit
退出或从main
返回,从而使数据未打印。参见Using printf in assembly leads to an empty ouput
您可以使用ltrace ./my_program
查看它进行的库函数调用。