0

AT&T構文を使用して、32ビットLinuxアセンブリに移植したい80836DOSアセンブリのコードを見つけました。

いくつかの違いを説明しているが、レジスターについてのみ説明しているサイトを見つけました。元:

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

そのため、次のコードの変換で問題が発生しました。

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

私はこのコードを変換しています

私はそれを思います:

  1. sub al、57h ---> sub $ 0x57、%alおよびETC(わからない)

最悪の問題は、AT&Tアセンブリでは次のようなものであるため、割り込みにあります。

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

そしてDOS16では16時間?20時間?21時間?ああ、それでもint 20hは割り込みおよび値(mov dl、20h)として機能しますか?とても紛らわしい。

誰かが私を助けることができますか?

@EDITこのように変換しましたが、セグメンテーション違反エラーが発生しました。私はそれが割り込みについてであるとほぼ確信しています。

.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

誰?

4

1 に答える 1

3

マイナーな問題

おそらく、コードの「変換」の主な問題は、実際には当てはまらない「80836アセンブリ」および「at&t」という用語でいくつかのアイデアを結び付けているように見えることです。

これは命名規則の問題かもしれませんが、「80386アセンブリ」と「at&t」の違いはありませんが、Intel構文とat&t構文の両方を使用してx86アセンブリコードを記述できるため、「intel」と「at&T構文」の違いはありません。 。

GNUアセンブラを使用している場合(Intelの代わりにAT&T構文を使用している他の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」の使用に変換しようとしているだけでなく、に移植しようとしていることのようです。別のアドレッシングモードとb。別のオペレーティングシステム。

特に、割り込み呼び出し規約についての質問は、16ビットDOSコードをLINUXマシンで実行されているある種の32ビットコードに移植しようとしているという仮定につながります。

与えられたコードを「再利用」してシステムコールを実行するだけでは、さまざまな呼び出し規約が関係しているため、番号を置き換えるだけでは不可能です。

コードを修正しようとする可能性があるのは、BIOS割り込みの代わりにsyscallreadを使用して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 

DOSシステムコールメカニズムint0x21を利用するコードは、次のようなものを使用してさらに修正する必要があります。

    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

最後のステップは、exitsyscallを修正することです。

    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_APIint 0x20を見るとint 0x21、サンプルコードで何が使用されているかを理解するのに役立ちます。

  • BIOS割り込みの検索もウィキペディアがあなたの友達です:http://en.wikipedia.org/wiki/Bios_interruptがあなたの質問に答えるはずです。

    あなたの場合、それはinであるint 0x16-したがって:文字を読む。0ah

于 2013-03-24T10:42:58.817 に答える