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中进行操作的好方法,从语法基础到巧妙的优化技巧。关于:
GNUas
不允许这样做,除非有比十六进制常量+注释更难阅读的内容:
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