1

私はLinuxを使用しており、nasmとgasを試しています。c ++を使用してwprintfを使用してUnicode文字を印刷できます

#include <wchar.h>
#include <locale.h>
#include <stdio.h>
int main() 
{
  //printf("helloworld"); // can't do this AND wprintf in same program
  setlocale(LC_ALL, "");
  wprintf(L"%lc",0x307E); //prints out japanese hiragana ma ま
}

ただし、アセンブリでそれを実行しようとすると非常に混乱します(インテルとガスの両方の構文)。私の主な混乱は、.dataセクションにあります。gcc に -S スイッチを指定して、彼らがどのようにそれを行うかを確認しました。彼らは、13 の .string ステートメントでフォーマット文字列を実行します。その多くは空白の文字列で、各文字は個別の .string にあります。文字列をdbではなくdwに配置することで、基本的にnasmで通常の文字列をワイド文字列にすることができると読みました。もちろん、ガスの .int を試してみましたが、うまくいきません。つまり、余分な灰色の疑問符が出力されます。ここに私の現在のコードがあります

.section .data
locale:
  .string ""
printformat:
  .int '%','l','c'
printwide:
  .int 0x307E,0
.section .text
.global _start
_start:
movq    $locale,%rsi
movq    $6,%rdi
call    setlocale
movq    $printformat,%rdi
movq    $printwide,%rsi
movq    $0,%rax
call    wprintf
movq    $2,%rdi
call    exit

これにより、5 つのクエスチョン マークがグレー表示され、次にひらがなま (ma) が表示されます。'%','l','c' の後に ,0 があるはずだと思うかもしれませんが、それは機能しません。それを実行すると、疑問符だけが出力されます。ひらがなマと疑問符なしで印刷できる唯一の方法は、フォーマット文字列をスキップして、printwide を rdi にロードすることです。

繰り返しますが、これは現時点では教育目的のためのものです。基本的に、at&t 構文と intel の両方でフォーマット文字列をどのように行うのですか? C++ では、単に L を前に置きます。(そして、はい、%lc を 16 進数に変更できると思いますが、そのようにしたくありません)

編集 これは機能します( $printwide を printwide に変更し、 printformat: を gcc -S リストのように .strings に変更しました。)しかし、なぜ機能するのでしょうか。 ? そして、インテルの構文でどのようにしますか?

.section .data
locale:
    .string ""
printformat:
    .string "%"
    .string ""
    .string ""
    .string "l"
    .string ""
    .string ""
    .string "c"
    .string ""
    .string ""
    .string ""
    .string ""
    .string ""
    .string ""
printwide:
    .word 0x307E
.section .text
.global _start
_start:
movq    $locale,%rsi
movq    $6,%rdi
call    setlocale
movq    $printformat,%rdi
movq    printwide,%rsi
movq    $0,%rax
call    wprintf
movq    $2,%rdi
call    exit
4

1 に答える 1

1

私はその答えに驚いています。64ビット幅の文字は32ビットだと思います。nasmを読んでこれを見つけました。次の方法で、インテル構文で文字列 utf-16 を作成できます。

printformat dw __utf16__("%lc"),0

ただし、それは私がしたときにのみ機能しました

printformat dd __utf32__("%lc"),0

したがって、at&t 構文で同等のものは次のようになります。

.long '%','l','c',0

非常に多くの文字列を使用した gcc -S のリストにより、32ビット幅になると思います

.string "%" = 16 ビット (% と自動ゼロ)、次に空の文字列を持つ別の 8 ビット、別の空の文字列を持つ別の 8 ビット。

于 2013-08-06T17:48:48.220 に答える