如何在Intel x86汇编中不修改数据段打印"Hello Luck"?
问题:不修改原有.data段且不新增数据段打印"Hello Luck"
原始汇编代码
.global main .data helloworld: .ascii "Hello world\n" helloworldend: goodluck: .asciz "Good Luck!\n" goodluckend: .text main: # printf(helloworld) movq $1, %rax movq $1, %rdi movq $helloworld, %rsi movq $helloworldend-helloworld, %rdx syscall # printf(goodluck) movq $1, %rax movq $1, %rdi movq $goodluck, %rsi movq $goodluckend-goodluck, %rdx syscall xorq %rax, %rax ret
需求:在不修改现有.data段内容的前提下,额外打印"Hello Luck"字符串。
你当前的实现方式是在main函数内插入.data段定义新字符串:
... main: .section .data msg: .ascii "Hello Luck\n" msgend: .section .text start: movq $1, %rax movq $1, %rdi movq $msg, %rsi movq $msgend-msg, %rdx syscall ...
这种方法能运行,但本质是在原有.data段中新增了数据,严格来说属于修改了.data段。如果要完全符合“不修改原有.data段且无需新增数据段”的要求,可以利用栈空间临时构造字符串,具体实现如下:
栈上构造字符串的实现
.global main .data helloworld: .ascii "Hello world\n" helloworldend: goodluck: .asciz "Good Luck!\n" goodluckend: .text main: # 打印Hello world movq $1, %rax movq $1, %rdi movq $helloworld, %rsi movq $helloworldend-helloworld, %rdx syscall # 栈上构造并打印Hello Luck\n subq $11, %rsp # 为11字节的字符串分配栈空间 # 逐个写入字符串字节 movb $0x48, (%rsp) # 'H' movb $0x65, 1(%rsp) # 'e' movb $0x6C, 2(%rsp) # 'l' movb $0x6C, 3(%rsp) # 'l' movb $0x6F, 4(%rsp) # 'o' movb $0x20, 5(%rsp) # ' ' movb $0x4C, 6(%rsp) # 'L' movb $0x75, 7(%rsp) # 'u' movb $0x63, 8(%rsp) # 'c' movb $0x6B, 9(%rsp) # 'k' movb $0x0A, 10(%rsp) # '\n' # 调用sys_write打印 movq $1, %rax movq $1, %rdi movq %rsp, %rsi movq $11, %rdx syscall addq $11, %rsp # 恢复栈指针,避免栈不平衡 # 打印Good Luck! movq $1, %rax movq $1, %rdi movq $goodluck, %rsi movq $goodluckend-goodluck, %rdx syscall xorq %rax, %rax ret
原理说明
- 栈属于进程的栈段,不属于
.data数据段,因此在栈上构造字符串不会修改原有.data段,也无需新增任何数据段。 - 通过调整栈指针分配临时空间,逐个写入字符串的ASCII字节,然后直接将栈地址作为字符串指针传递给
sys_write系统调用完成打印,最后恢复栈指针保证栈平衡。
内容的提问来源于stack exchange,提问作者SpaceNugget
相关产品推荐
相关产品推荐

