【问题标题】:Porting yasm code (Intel style) to gas (AT&T style)将 yasm 代码(英特尔风格)移植到 gas(AT&T 风格)
【发布时间】:2019-05-24 17:24:21
【问题描述】:

我正在尝试了解汇编 x86 32 位中的字符串,但最近从 yasm 切换到 gas 并尝试翻译源文件顺便说一句我使用 xorpd 代码你可以看到 here 我看到了一些 AT&T 语法,我尝试翻译 include file 但我没有翻译它我不知道问题出在哪里,如果有人能告诉我代码中的问题在哪里。

字符串.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

【问题讨论】:

  • 您能否将strings.s的相关部分直接添加到问题中而不是链接。
  • 关于 Stack Overflow 的问题必须是独立的。请生成minimal reproducible example 并将其放入您的问题中。不要在您的问题中放置代码链接。当您链接的所有网站都关闭时,您的问题必须仍然有意义。
  • movl ARRLEN, %ecx 必须是 $ARRLEN,因为您需要一个直接常量,而不是负载。
  • 不工作仍然同样的错误彼得
  • 请注意,gas 可以执行 intel 语法。也许与 yasm 不同,但可能比切换到 at&t 更容易解决。

标签: assembly x86-64 gnu-assembler yasm


【解决方案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 语法更容易且不易出错。

【讨论】:

    猜你喜欢
    • 2012-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多