2つのソースファイルがあります.1つはアセンブリで、もう1つはcです。アセンブリには、cソース内の静的文字列への参照が含まれています。私はcソースから呼び出されたアセンブリ内の関数を定義し、ヒッチがなくても正常に動作します。しかし、アセンブリからprintfを呼び出して、引数としてCソースファイルの文字列を渡そうとすると、出力が文字化けするか、まったく出力されません。アセンブリソースが引数を正しく渡すことができません
nasmを使用してelf32-i386にアセンブリをコンパイルし、gccを使用してcファイルをコンパイルします。私はデバッグ情報の有無にかかわらず試してみましたが、幸いにも同じ結果が得られました。
main.s:
SECTION .text
global s_func
extern c_str
extern printf
s_func:
sub esp, 4
mov dword [esp], c_str
call printf
add esp, 4
ret
はmain.cの:
#include <stdio.h>
const char* c_str = "Sup.";
extern void s_func(void);
int main(void)
{
printf(c_str); //prints as expected
s_func(); //weird stuff
}
のMakefile:
main : main.o main.s.o
gcc main.o main.s.o -o main
main.o :
gcc -g -c main.c -o main.o
main.s.o :
nasm -f elf main.s -o main.s.o
ここではその一部だ。ここ
は、単純なソースファイルがありますあなたがこれらを集めたら、私を得る2つのファイルがオブジェクトにリンクされていれば、printfの呼び出しがどちらのソースでも同じであることがわかります。コードセグメントは同じで、c_strには両方のアセンブリリストに同じアドレスが含まれています。 main.cの中
コール:main.sで
printf(c_str); //prints as expected
80483ed: a1 14 a0 04 08 mov 0x804a014,%eax
80483f2: 89 04 24 mov %eax,(%esp)
80483f5: e8 06 ff ff ff call 8048300 <[email protected]>
コール
08048410 <s_func>:
8048410: 83 ec 04 sub $0x4,%esp
8048413: b8 14 a0 04 08 mov $0x804a014,%eax
8048418: 89 04 24 mov %eax,(%esp)
804841b: e8 e0 fe ff ff call 8048300 <[email protected]>
8048420: 83 c4 04 add $0x4,%esp
8048423: c3 ret
は、たぶん私はいくつかのレジスタを保存することとしていますか?私はs_func上で通常のスタックフレームをセットアップしましたが、それはまだ失敗します。
値の代わりにc_strのアドレスをプッシュしているようです。デバッガのコードをステップ実行します。 –
c_strは、そうでなければならないポインタです。それはまったく同じです。 $記号は意味がありますか? – chaz
main.sのコードがソースコードと一致しません。元のコードはeaxをロードしませんでした。何かが足りない。多分あなたは間違ったコードを見ているでしょう。 –