Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Gcc 垃圾`(0,1,1)和#x27;表达后_Gcc_Assembly_Gnu Assembler_X86 - Fatal编程技术网

Gcc 垃圾`(0,1,1)和#x27;表达后

Gcc 垃圾`(0,1,1)和#x27;表达后,gcc,assembly,gnu-assembler,x86,Gcc,Assembly,Gnu Assembler,X86,当我尝试组装程序时,会收到以下一系列错误消息: misha@hp-laptop:~/test$ as -gstabs test.s -o test.o && ld test.o -o a.out && rm test.o && ./a.out test.s: Assembler messages: test.s:19: Error: junk `(0,0,1)' after expression test.s:20: Error: junk `(0

当我尝试组装程序时,会收到以下一系列错误消息:

misha@hp-laptop:~/test$ as -gstabs test.s -o test.o && ld test.o -o a.out && rm test.o && ./a.out
test.s: Assembler messages:
test.s:19: Error: junk `(0,0,1)' after expression
test.s:20: Error: junk `(0,1,1)' after expression
test.s:21: Error: junk `(0,2,1)' after expression
test.s:22: Error: junk `(0,3,1)' after expression
谁能告诉我我到底做错了什么,我的程序无法运行?显然,这与我试图访问数组元素的方式有关,每个数组元素都有一个字节长。以下是程序本身:

/******************************************************************************
 *                                                                            *
 * This program prints the string "foo" on the console.                       *
 *                                                                            *
 ******************************************************************************/

.section .data
    array: .byte 0x00, 0x00, 0x00, 0x00  # An array of four bytes
    size:  .int  4                       # The size of the array


.section .text
.globl _start
_start:
    movb   $0x66, %ah   # 66 is the hexadecimal value for 'f'
    movb   $0x6F, %al   # 6F is the hexadecimal value for 'o'
    movb   $0x6F, %bh   # 6F is the hexadecimal value for 'o'
    movb   $0x0A, %bl   # A is the hexadecimal value for '\n'
    movb   %ah, array(0, 0, 1)
    movb   %al, array(0, 1, 1)
    movb   %bh, array(0, 2, 1)
    movb   %bl, array(0, 3, 1)

    # print
    movl   $4, %eax       # 4 is the number for the write system call
    movl   $1, %ebx       # The file descriptor to write to (1 - STDOUT)
    movl   $array, %ecx   # The starting address of the string to print
    movl   size, %edx     # The number of bytes to print
    int    $0x80          # Wake up the kernel to run the write system call

    # exit
    movl   $1, %eax       # 1 is the number for the exit system call
    movl   $0, %ebx       # Exit status code (echo $?)
    int    $0x80          # Wake up the kernel to run the exit system call

/*

Compile and run:

as -gstabs test.s -o test.o && \
ld test.o -o a.out && \
rm test.o && \
./a.out

*/

问题在于如何引用数组成员。改用这个:

movb   %ah, array + 0
movb   %al, array + 1
movb   %bh, array + 2 
movb   %bl, array + 3

多维数组没有asm语法,除非您自己用宏构建它。或者,您可以通过在
(基本、索引、缩放)
语法中将未使用的寄存器替换为
0

您可以使用一个包含a的数组来从中获取偏移量,如
movb$constant,array+4

查看编译器输出通常是学习如何在asm中进行操作的好方法,从语法基础到巧妙的优化技巧。关于:

GNU
as
不允许这样做,除非有比十六进制常量+注释更难阅读的内容:

movl $('f' | 'o'<<8 | 'o'<<16 | '\n'<<24), array

还要注意的是,
movl$constant,(%ecx)
movl$constant,array
需要更少的字节进行编码,因此您可以通过尽早将
$array
放入
%ecx
中,然后使用简单的寄存器寻址模式来节省代码字节。

我建议将手写的asm源代码保存在
.S
,不是
.s
gcc-S test.c
将在不询问的情况下关闭
test.S
,但默认情况下,任何东西都不会将
.S
用作输出文件扩展名。例如,glibc的所有asm源文件都是
.s
。您还可以使用
gcc-m32-nostlib test.S
轻松编译。希望您的笔记本电脑没有运行32位Linux,因此您需要
-m32
来运行32位代码。由于
int 0x80
ABI仍然可用,因此此代码实际上可能在64位模式下工作,但只要您修改
%esp
而不是
%rsp
,您就完蛋了。请参阅,以及中的其他链接
mov    dword [array+off], `foo\n`    ;backquote for C-style \-escapes, unlike '' or ""
movl $('f' | 'o'<<8 | 'o'<<16 | '\n'<<24), array
##  size:  .int  4   # Don't need this stored in memory anywhere
.equ size, 4
...

movl   $array, %ecx   # The starting address of the string to print
movl   $size, %edx    # The number of bytes to print