程序集、系统调用未按预期工作。 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,则需要将 0x310x32'1''2')加载到内存区域(使其变大够了)使用 2 作为长度。

例如,movw [=19=]x3231, output 或更好的 movw [=20=]x3231, output(%rip) 以对静态数据使用 RIP 相对寻址,就像 x86-64 的正常情况一样。 (与 NASM 不同,GAS 语法不会 $'12' 作为写入相同整数常量的方式。)

如果您想将一个整数打印为字符串,您可能需要对其进行数学运算,这样您就可以一次处理一个数字。 ()