Question

I found code in 80836 DOS assembly that I'd like to port to 32-bit Linux assembly, using AT&T syntax.

I found site that explains some differences but only about registers. EX:

  1. cmp al, 'A' -> cmp 'A', %al

So I got problems converting following code:

input:
    mov ah, 00h
    int 16h
    cmp ah, 1ch
    je exit

sub al, 30h

sub al, 37h

sub al, 57h

mov ah, 02h
mov dl, al
int 21h

        mov dl, 20h
        int 21h

exit:
        int 20h

I am converting this code

I think that:

  1. sub al, 57h ---> sub $0x57, %al and ETC (not sure)

The worst problem is with interrupts since in AT&T assembly it's like:

SYSCALL = 0X80
SYSEXIT = 1
EXIT_SUCCESS = 0
SYSREAD = 3
SYSWRITE = 4
STDIN = 0
STDOUT = 1  

And in DOS16, 16h? 20h? 21h? oh man, and even then int 20h acts as interrupt and as value (mov dl, 20h)? so confusing.

Can someone help me?

@EDIT I converted it like this, but I got segmentation fault error. I am almost sure it's about interrupts..

.data
.text
.global _start

_start:

input:
        movb $0x0,%ah
        int $0x16
        cmpb $0x1c,%ah
        je exit

number:
        cmpb $'0', %al
        jb input
        cmpb $'9', %al
        ja uppercase
        subb $0x30,%al
        call process
        jmp input

uppercase:
        cmpb $'A', %al
        jb input
        cmpb $'F', %al
        ja lowercase
        subb $0x37,%al
        call process
        jmp input

lowercase:
        cmpb $'a', %al
        jb input
        cmpb $'f', %al
        ja input
        subb $0x57,%al
        call process
        jmp input

loop input

process:
        movb $4,%ch
        movb $3,%cl
        movb %al,%bl

convert:
        movb %bl,%al
        rorb %cl,%al
        andb $01,%al
        addb $0x30,%al

        movb $0x2,%ah
        movb %al,%dl
        int $0x21

        decb %cl
        decb %ch
        jnz convert

        movb $0x20,%dl
        int $0x21
ret

exit:

        int $0x20

Anyone?

Was it helpful?

Solution

Minor Problem

Probably the main problem of your code "conversion" is that you seem to connect some ideas with the terms "80836 assembly" and "at&t" that don't really apply.

Although this might just be a matter of naming conventions there is no "80386 assembly" vs. "at&t" difference but a "intel" vs. "at&T syntax" difference as both intel syntax and at&t syntax can be used to describe x86 assembly code.

If you are using GNU assembler (I don't know any other x86 assembler using AT&T syntax instead of intel) you might just want to use .intel_syntax and stay with the intel syntax used in your reference material instead.

.intel_syntax noprefix
; your code in intel syntax here
.att_syntax prefix
; code in at&t syntax here

Don't forget to switch to 16-bit mode.code16 if you intend to use it in real mode.

Bigger Problem

The far the bigger problem with your question seems to be that you are not only trying to transform the code from using "intel-syntax" to using "at&t-syntax" but rather to port it to a. another addressing mode and b. another operating system.

Especially your question about interrupt calling conventions leads me to the assumption you are trying to port 16-bit DOS code to some kind of 32-bit code running on a LINUX machine.

Just "reusing" the given code to perform system calls won't be possible by simply replacing numbers as there a different calling conventions involved.

Things you might try to fix your code include using syscall read instead of BIOS interrupt to read from stdin

storage:
   .ascii " "

#  ... 

    movl $3, %eax      # syscall number 
                       # (check syscall.h to see if it's  3 on your system)
    movl $0, %ebx      # file descriptor (0 designating stdin)       
    movl $storage, %ecx
    movl $1, %edx      # number of chars to read
    int $0x80 

Code utilizing DOS syscall mechanism int 0x21 would have to be fixed in addition using something like

    movl $4, %eax      # syscall number write
    movl $0, %ebx      # file descriptor (1 designating stdout)       
    movl $storage, %ecx
    movl $1, %edx      # number of chars to write
    int $0x80

The last step should be fixing the exit syscall:

    movl $1, %eax      # syscall number exit
    movl $0, %ebx      # it doesn't hurt to set a reasonable exit code here.
    int $0x80

Requested Documentation Source

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top