私は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