0

I'm trying to learn about strings in assembly x86 32bit but recently switched from yasm to gas and tried translating the sources file btw I used xorpd code you can see here I saw some AT&T syntax and I tried translating include file but However I failed to translate it I don't know where is the problem and if someone can tell me where is the problem in my code.

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

Compiler fails.

$ gcc-9 -m32 strings.s -o strings
strings.s: Assembler messages:
strings.s:1: Error: missing string
Rohit
  • 17
  • 4
  • Could you add the relevant portion of strings.s to the question directly instead of links. –  May 24 '19 at 17:26
  • 1
    Questions on Stack Overflow must be self-contained. Please produce an [MCVE] and put it in your question. Do not put links to code in your question. Your question must still make sense when all sites you link to go down. – fuz May 24 '19 at 17:37
  • `movl ARRLEN, %ecx` needs to be `$ARRLEN` because you want an immediate constant, not a load. – Peter Cordes May 24 '19 at 17:58
  • Not working still same error Peter – Rohit May 24 '19 at 18:14
  • 3
    Note that gas can do intel syntax. Maybe not the same as yasm but probably easier to fix that than to switch to at&t. – Jester May 24 '19 at 18:25
  • Missing string I just don't know where I missed any strings – Rohit May 25 '19 at 01:32
  • instead of doing the hard work of replacing register names and swapping the operands, just tell gas to use Intel syntax. [How do you use gcc to generate assembly code in Intel syntax?](https://stackoverflow.com/q/199966/995714), [Can I use Intel syntax of x86 assembly with GCC?](https://stackoverflow.com/q/9347909/995714) – phuclv May 25 '19 at 02:22

1 Answers1

1

The problem is the first line. GAS requires all strings (including file names) to be double-quoted.

.include "fn.s" not 'fn.s' single quotes.


GAS doesn't accept multi-character character literals like 'abc' as numeric literals either, the way YASM and NASM do. In fact it totally breaks parsing and it prints nonsense error messages.

.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'

Note that line 5 is blank, and the file does end with a newline (but it's at the end of a line containing a single quote.)


Single-character literals work as integers, like add $'0', %eax or .long 'b'.

Or in .intel_syntax noprefix, as add eax, '0'


You should probably use .intel_syntax noprefix

Mostly just put OFFSET into mov reg, symbol (making it mov reg, OFFSET symbol) to get the mov-immediate encoding, and port the directives. Much easier and less error-prone than manually changing everything to AT&T syntax.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847