【发布时间】:2020-07-15 05:52:48
【问题描述】:
我试图在 Assembly 的不同行上打印多个字符串,但使用我的代码,它只打印最后一个字符串。我对汇编语言很陌生,所以请多多包涵
section .text
global _start
_start:
mov edx, len
mov edx, len1
mov edx, len2
mov edx, len3
mov ecx, msg
mov ecx, str1
mov ecx, str2
mov ecx, str3
mov ebx, 1
mov eax, 4
int 0x80
mov eax, 1
int 0x80
section .data
msg db 'Hello, world!',0xa
str1 db 'Learning is fun!',0xa
str2 db 'I love beacon!',0xa
str3 db 'I love programming',0xa
len1 equ $ - str1
len2 equ $ - str2
len3 equ $ - str3
len equ $ - msg
它只会打印出我喜欢编程。
假设打印
Hello World!
Learning is fun!
I love beacon!
I love programming
【问题讨论】:
-
int 0x80调用内核,此时它会找出您想要从 EAX 获得的 哪个 系统调用,并在其他 regs 中使用 args。您只进行write系统调用,并在此之前浪费了一堆指令覆盖具有不同值的寄存器。使用调试器单步查看寄存器值的变化,并使用strace ./my_program跟踪系统调用。 -
另外,除了
len3,你所有的长度都是错误的,它恰好是你实际使用的那个。 (How does $ work in NASM, exactly? / In NASM labels next to each other in memory are causing printing issues) 例如len是所有字符串组合的总长度,因此您当然可以使用一次写入系统调用打印整个 ASCII 文本块。 -
@PeterCordes 我不明白在这里做什么
-
要么使用多个
int 0x80指令进行多个write系统调用,要么将指向msg的指针和整个文本块的长度传递给一个write系统调用。内核只能看到int 0x80运行时寄存器中的值,而不是调用内核之前覆盖该寄存器4次的历史。