Linux 如何在汇编语言的新行上打印多个字符串
我试图在汇编中的不同行上打印多个字符串,但在我的代码中,它只打印最后一个字符串。我对汇编语言很陌生,所以请耐心听我说Linux 如何在汇编语言的新行上打印多个字符串,linux,assembly,x86,Linux,Assembly,X86,我试图在汇编中的不同行上打印多个字符串,但在我的代码中,它只打印最后一个字符串。我对汇编语言很陌生,所以请耐心听我说 section .text global _start _start: mov edx, len mov edx, len1 mov edx, len2
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
你期待什么
您正在覆盖寄存器edx
这与其他编程语言中的以下代码类似:
variableEdx = len;
variableEdx = len1;
第二行将覆盖变量variableEdx
,第一行的效果将消失
如何打印多个字符串
函数eax=4
将内存中的一些数据从某个地址开始,到某个设备的某个地址结束
如果第二个字符串紧跟在内存中的第一个字符串之后,则可以将由两个字符串组成的内存发送到设备
例如:
...
mov edx, str1
mov ecx, 32
...
.text
.globl _start
_start:
mov edx, 3
mov ecx, offset list
mov ebx, 1
mov eax, 146
int 0x80
mov eax, 1
int 0x80
.data
list:
.long msg
.long 7
.long str1
.long 8
.long str3
.long 19
...
这将从str1
开始向设备发送32字节的内存内容。从str1
开始的32个字节是字符串str1
和str2
如果要向设备发送多个内存块,可以使用writev()
系统调用,即functioneax=146
。(见附件)
例如:
...
mov edx, str1
mov ecx, 32
...
.text
.globl _start
_start:
mov edx, 3
mov ecx, offset list
mov ebx, 1
mov eax, 146
int 0x80
mov eax, 1
int 0x80
.data
list:
.long msg
.long 7
.long str1
.long 8
.long str3
.long 19
...
不幸的是,我使用的汇编程序的语法与您的略有不同;但是,在部件中,列表
零件可能如下所示:
list dd msg
dd 7
dd str1
...
writev
(函数146)获取指向ecx
寄存器中某个“列表”的指针以及edx
寄存器中列表中的条目数
列表中的每个条目由两个32位字组成。第一个字是要写入设备的存储器的地址;第二个字是要写入的字节数
上面的例子写着“你好,学习我喜欢编程”:
“msg”的前7个字节,然后是“str1”的前8个字节,然后是“str3”的所有19个字节。
int 0x80
调用内核,在这一点上,它指出您想要从EAX调用哪个系统,并在其他regs中使用args。您只需执行write
系统调用,并浪费大量指令覆盖之前具有不同值的寄存器。使用调试器单步执行并查看寄存器值的变化,并使用strace./my_program
跟踪系统调用。此外,除了实际使用的len3
之外,所有长度都是错误的。(/)例如,len
是所有字符串组合的整个长度,因此您当然可以使用一个write syscall打印整个ASCII文本块。@PeterCordes我不明白在这里该怎么做可能是重复的,或者可能是使用多个int 0x80
指令进行多个write
系统调用,或者将指向msg
的指针和整个文本块的长度传递给一个write
系统调用。内核只能在运行int 0x80
时看到寄存器中的值,而不能看到在调用内核之前覆盖该寄存器4次的历史记录。EAX=146是writev
系统调用;您应将其命名并链接到手册页: