在 GAS 中进行系统调用并使用 .data 部分中的变量并在另一个子程序中访问它们以进行系统调用 [英] Making a system call in GAS and using variables in .data section and accessing them for a system call inside another sub-routine
问题描述
这是我使用 GAS 语法为 64 位英特尔程序集编写的代码示例.当代码运行时,期望打印出字符串:在 _print 子例程中.
Here is the code example that I have written using GAS syntax for 64 bit intel assembly. When the code is run the expectation is to print out the string: Inside the _print subroutine.
#This example is a an example to call a subroutine
.global _start
.section .text
_start:
call _print
_exit:
#exit call
mov $60, %rax
xor %rdi, %rdi
syscall
_print:
#set up the stack frame
push %rbp
mov %rsp, %rbp
# write syscall's parameter set up
mov std_out_fd, %rdi
mov $message, %rsi
movq message_size, %rdx
mov write_syscall_no, %rax
syscall
#Restore callers registers value
#pop %rdx
#pop %rsi
#pop %rdi
#Destroy the stack frame:
mov %rbp, %rsp
pop %rbp
ret
.section .data
std_out_fd: .int 0x02
message: .ascii "Inside the _print subroutine.\n"
message_size: .byte 30
write_syscall_no: .int 0x01
==========================================
=========================================
当我尝试使用声明的变量message_size"作为 write 系统调用的第三个参数时,我在屏幕上打印消息后打印了一些奇怪的额外字符:
When I try to use the declared variable 'message_size' as the third parameter for the write system call I get a few weird extra characters printed after the message is printed on the screen:
ali@alix2:~/Programming/asm/GAS-Syntax/SubRoutine$ as -o subroutine.o subroutine.s
ali@alix2:~/Programming/asm/GAS-Syntax/SubRoutine$ ld -o subroutine subroutine.o
ali@alix2:~/Programming/asm/GAS-Syntax/SubRoutine$ ./subroutine
Inside the _print subroutine.
`;`Qali@alix2:~/Programming/asm/GAS-Syntax/SubRoutine$
但是当我没有使用变量时,我将其更改为移动 $30,%rdx
but when instead of using the variable I change it to mov $30, %rdx
然后它完美地工作并且没有额外的字符(;
Q)将被写入标准输出.
then it works perfectly and none of the extra characters(;
Q) will be written to stdout anymore.
ali@alix2:~/Programming/asm/GAS-Syntax/SubRoutine$ ./subroutine
Inside the _print subroutine.
ali@alix2:~/Programming/asm/GAS-Syntax/SubRoutine$
谁能解释一下这背后的原因?谢谢.
Could anyone explain the reason behind this? Thanks.
推荐答案
movq message_size, %rdx
是 64 位 (qword) 加载,包括 .byte 30
和 .int 0x1
,以及 3 个字节.使用调试器(例如 GDB)查看寄存器中的值.并使用 strace ./subroutine
来跟踪系统调用,并表明您正在向 write
传递一个巨大的长度.
movq message_size, %rdx
is a 64-bit (qword) load that include the .byte 30
, and the .int 0x1
, and 3 bytes past that. Use a debugger (GDB for example) to look at values in registers. And use strace ./subroutine
to trace system calls and show that you're passing a huge length to write
.
您可以使用 movzbl message_size(%rip), %edx
加载将该字节零扩展到 RDX.
You could use a movzbl message_size(%rip), %edx
load to zero-extend that byte into RDX.
或者更好的是,让汇编程序为您计算大小作为汇编时间常数.equ message_size, .- message
以便您可以使用 $message_size
作为即时消息.无需单独硬编码大小或将其存储在数据存储器中.
Or better, let the assembler calculate sizes for you as assemble-time constants with
.equ message_size, . - message
so you can use $message_size
as an immediate. No need to hard-code the size separately or to store it in data memory.
电话号码相同;不要为它做 64 位加载,尤其不要从 32 位 .int
加载!如果在那之后 .data
中有任何其他内容,它会将垃圾加载到 RAX 的高字节中.你可以只是 mov
到 EAX,它隐式地零扩展到 RAX.
Same for the call number; don't do a 64-bit load for it, especially not from a 32-bit .int
! If you had any other stuff in .data
after that, it would load garbage into the high bytes of RAX. You could just mov
into EAX which zero-extends into RAX implicitly.
这篇关于在 GAS 中进行系统调用并使用 .data 部分中的变量并在另一个子程序中访问它们以进行系统调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!