将Yasm代码(Intel样式)移植到gas(AT&T样式)

时间:2019-05-24 17:24:22

标签: assembly x86-64 gas yasm

我正在尝试了解汇编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

1 个答案:

答案 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语法相比,这更容易且更不容易出错。