程序集、系统调用未按预期工作。 Ubuntu Linux x86_64 ,使用 AT&T 语法
Assembly , syscall not work as expected. Ubuntu Linux x86_64 , using AT&T syntax
我正在测试使用 .bss 分配内存区域以保存单个数字。然后将该数字打印到控制台。输出不符合预期。我应该得到 e 号码 (12),但得到一个换行符。
系统配置:
$ uname -a
Linux 5.8.0-48-generic #54~20.04.1-Ubuntu SMP Sat Mar 20 13:40:25 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
description: CPU
product: Intel(R) Core(TM) i5-8350U CPU @ 1.70GHz
代码:
# compile with: gcc -ggdb -nostdlib -no-pie test.s -o test
.bss
.lcomm output,1
.global _start
.text
_start:
# test .bss and move numer 12 to rbx where memory are allocated in .bss
mov $output, %rbx # rbx to hold address of allocated space
mov ,%rdx # Move a number to rdx
mov %rdx,(%rbx) # Move content in rdx to the address where rbx points to (e.g ->output)
# setup for write syscall:
mov ,%rax # system call for write, according to syscall table (http://blog.rchapman.org/posts/Linux_System_Call_Table_for_x86_64/)
mov ,%rdi # fd = 1, stdout
mov $output,%rsi # adress of string to output moved to rsi
mov ,%rdx # number of bytes to be written
syscall # should write 12 in console
mov ,%rax
xor %rdi,%rdi
syscall # exit normally
我已经在第一个系统调用(使用 GDB)中设置了一个断点,以查看寄存器:
i r rax rbx rdx rdi rsi
rax 0x1 1
rbx 0x402000 4202496
rdx 0x1 1
rdi 0x1 1
rsi 0x402000 4202496
x/1 0x402000
0x402000 <output>: 12
系统调用后的输出为空,预期得到数字“12”:
:~/Dokumenter/ASM/dec$ gcc -ggdb -nostdlib -no-pie test.s -o test
:~/Dokumenter/ASM/dec$ ./test
:~/Dokumenter/ASM/dec$ ./test
:~/Dokumenter/ASM/dec$
那么,我的问题是,是否有任何明显的解释可以解释为什么我得到的是空白而不是 12?
mov $output,%rsi # address of string to output moved to rsi
^^^^^^
字符串的地址。值</code>是<em>不是</em>字符序列 <code>"12"
。如果要打印字符串 12
,则需要将 0x31
和 0x32
('1'
和 '2'
)加载到内存区域(使其变大够了)使用 2
作为长度。
例如,movw [=19=]x3231, output
或更好的 movw [=20=]x3231, output(%rip)
以对静态数据使用 RIP 相对寻址,就像 x86-64 的正常情况一样。 (与 NASM 不同,GAS 语法不会 $'12'
作为写入相同整数常量的方式。)
如果您想将一个整数打印为字符串,您可能需要对其进行数学运算,这样您就可以一次处理一个数字。 ()
我正在测试使用 .bss 分配内存区域以保存单个数字。然后将该数字打印到控制台。输出不符合预期。我应该得到 e 号码 (12),但得到一个换行符。
系统配置:
$ uname -a
Linux 5.8.0-48-generic #54~20.04.1-Ubuntu SMP Sat Mar 20 13:40:25 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
description: CPU
product: Intel(R) Core(TM) i5-8350U CPU @ 1.70GHz
代码:
# compile with: gcc -ggdb -nostdlib -no-pie test.s -o test
.bss
.lcomm output,1
.global _start
.text
_start:
# test .bss and move numer 12 to rbx where memory are allocated in .bss
mov $output, %rbx # rbx to hold address of allocated space
mov ,%rdx # Move a number to rdx
mov %rdx,(%rbx) # Move content in rdx to the address where rbx points to (e.g ->output)
# setup for write syscall:
mov ,%rax # system call for write, according to syscall table (http://blog.rchapman.org/posts/Linux_System_Call_Table_for_x86_64/)
mov ,%rdi # fd = 1, stdout
mov $output,%rsi # adress of string to output moved to rsi
mov ,%rdx # number of bytes to be written
syscall # should write 12 in console
mov ,%rax
xor %rdi,%rdi
syscall # exit normally
我已经在第一个系统调用(使用 GDB)中设置了一个断点,以查看寄存器:
i r rax rbx rdx rdi rsi
rax 0x1 1
rbx 0x402000 4202496
rdx 0x1 1
rdi 0x1 1
rsi 0x402000 4202496
x/1 0x402000
0x402000 <output>: 12
系统调用后的输出为空,预期得到数字“12”:
:~/Dokumenter/ASM/dec$ gcc -ggdb -nostdlib -no-pie test.s -o test
:~/Dokumenter/ASM/dec$ ./test
:~/Dokumenter/ASM/dec$ ./test
:~/Dokumenter/ASM/dec$
那么,我的问题是,是否有任何明显的解释可以解释为什么我得到的是空白而不是 12?
mov $output,%rsi # address of string to output moved to rsi
^^^^^^
字符串的地址。值</code>是<em>不是</em>字符序列 <code>"12"
。如果要打印字符串 12
,则需要将 0x31
和 0x32
('1'
和 '2'
)加载到内存区域(使其变大够了)使用 2
作为长度。
例如,movw [=19=]x3231, output
或更好的 movw [=20=]x3231, output(%rip)
以对静态数据使用 RIP 相对寻址,就像 x86-64 的正常情况一样。 (与 NASM 不同,GAS 语法不会 $'12'
作为写入相同整数常量的方式。)
如果您想将一个整数打印为字符串,您可能需要对其进行数学运算,这样您就可以一次处理一个数字。 (