我正在尝试了解汇编x86 32位中的字符串,但最近从yasm切换为gas,并尝试翻译源文件,因为我使用了xorpd代码,可以看到here 我看到了一些AT&T语法,并尝试翻译include file,但是我未能翻译它,我不知道问题出在哪里,是否有人可以告诉我我的代码在哪里。
strings.s
.include 'fn.s'
.extern exit
ARRLEN = 5 /* equivalent to .set ARRLEN, 0x5 */
.data /* data section equivalent to .section .data */
saar: .long 3,5,8 /* array of 32bit integers */
daar: .fill ARRLEN, 4, 0 /* array of 32bit integers 4 bytes is size it's in format of
.fill repeat, size, value
i used it to intialize the array ARRLEN times with value 0*/
.text /* text section equivalent to .section .text */
.globl _start /* for ld compatibility reasons. equivalent to .global main */
_start:
movl ARRLEN, %ecx
movl $saar, %esi
xor %eax, %eax
_par:
call read_hex
stosl
loop _par
push $0
call exit
fn.s
.data
hex_new: .asciz "%x\n"
hex_: .asciz "%x"
dec_: .asciz "%d"
dec_new: .asciz "%d\n"
str_: .asciz "%s"
new_: .asciz "\n"
delim: .asciz "========\n"
.text
print_eax:
pushal
push %eax
push $hex_new
call printf
add $8, %esp
popal
ret
print_eax_dec:
pushal
push %eax
push $dec_new
call printf
add $8, %esp
popal
ret
print_delimiter:
pushal
mov $delim, %eax
push %eax
call printf
add $4, %esp
popal
ret
read_line:
pushal
push %ecx
push %edi
push $0
call read
add $12, %esp
xor %edx, %edx
movb $0, (%edi,%eax)
popal
ret
read_hex:
push %ebp
mov %esp, %ebp
sub $4, %esp
push %ebx
push %ecx
push %edx
lea -4(%ebp),%ebx
push %ebx
push $hex_
call scanf
add $8, %esp
movl (%ebx), %eax
pop %edx
pop %ecx
pop %ebx
leave
ret
read_dec:
push %ebp
movl %esp, %ebp
subl $4, %esp
lea -4(%ebp),%ebx
pusha
push %ebx
push $dec_
call scanf
add $8, %esp
popa
movl (%ebx), %eax
leave
ret
print_str:
pushal
push %esi
call printf
add $4, %esp
popal
ret
print_eax_binary:
pushal
movl $32, %ecx /* We print 32 digits. */
.print_digit:
rol $1, %eax
mov %eax,%edx
and $1, %edx
push %ecx
push %eax
push %edx
push $hex_
call printf
add $8, %esp
pop %eax
pop %ecx
loop .print_digit
push $new_
call printf
add $4, %esp
popal
ret
编译器失败。
$ gcc-9 -m32 strings.s -o strings
strings.s: Assembler messages:
strings.s:1: Error: missing string
答案 0 :(得分:1)
问题是第一行。 GAS要求所有字符串(包括文件名)都用双引号引起来。
.include "fn.s"
而不是'fn.s'
单引号。
GAS也不接受像'abc'
这样的多字符字符文字作为数字文字,就像YASM和NASM一样。实际上,它完全破坏了解析,并显示了无意义的错误消息。
.string 'abcd'
.include 'fn.s'
mov $'a', %eax
mov $'ab', %ax
.long 'abc'
strings.s: Assembler messages:
strings.s: Warning: end of file not at end of a line; newline inserted
strings.s:1: Error: junk at end of line, first unrecognized character is `9'
strings.s:2: Error: missing string
strings.s:5: Error: backward ref to unknown label "97:"
strings.s:5: Error: junk `44%ax' after expression
strings.s:5: Error: number of operands mismatch for `mov'
strings.s:6: Error: backward ref to unknown label "97:"
strings.s:6: Error: junk at end of line, first unrecognized character is `c'
请注意,第5行为空白,文件确实以换行符结尾(但它位于包含单引号的行的末尾。)
单字符文字用作整数,例如add $'0', %eax
或.long 'b'
。
或在.intel_syntax noprefix
中,以add eax, '0'
您可能应该使用.intel_syntax noprefix
通常只需将OFFSET
放入mov reg, symbol
(使其成为mov reg, OFFSET symbol
)中即可获得mov-immediate编码,并移植指令。与手动将所有内容更改为AT&T语法相比,这更容易且更不容易出错。