0

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?

4

1 回答 1

3

小问题

您的代码“转换”的主要问题可能是您似乎将一些想法与并不真正适用的术语“80836 程序集”和“at&t”联系起来。

尽管这可能只是命名约定的问题,但没有“80386 程序集”与“at&t”的区别,而是“intel”与“at&T 语法”的区别,因为intel语法和 at&t 语法都可用于描述 x86 汇编代码.

如果您使用的是 GNU 汇编器(我不知道任何其他使用 AT&T 语法而不是 intel 的 x86 汇编器),您可能只想使用.intel_syntax并保留参考资料中使用的 intel 语法。

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

.code16如果您打算在实模式下使用它,请不要忘记切换到 16 位模式。

更大的问题

您的问题更大的问题似乎是您不仅要尝试代码从使用“intel-syntax”转换为使用“at&t-syntax”,而且还要将其移植到a。另一种寻址方式和 b.另一个操作系统。

特别是您关于中断调用约定的问题使我假设您正在尝试将 16 位 DOS 代码移植到在 LINUX 机器上运行的某种 32 位代码。

仅仅通过简单地替换数字来“重用”给定的代码来执行系统调用是不可能的,因为涉及到不同的调用约定。

您可能尝试修复代码的事情包括使用系统调用读取而不是 BIOS 中断从标准输入读取

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 

使用 DOS 系统调用机制 int 0x21 的代码必须另外使用类似的东西来修复

    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

最后一步应该是修复退出系统调用:

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

要求的文档来源

  • 关于 DOS 系统调用,请查看http://en.wikipedia.org/wiki/MS-DOS_API应该有助于理解示例代码中的用途int 0x20int 0x21用途。

  • Seraching BIOS 中断也维基百科是你的朋友:http ://en.wikipedia.org/wiki/Bios_interrupt应该回答你的问题。

    在您的情况下,它int 0x160in ah- 因此:读取字符。

于 2013-03-24T10:42:58.817 回答