私はちょうど最近のように、私は初心者です、私はかなり簡単で基本的なプログラムを書いてきたと私は奇妙な(私に)気づいたように、私のアセンブリの旅を始めた。なぜ "rsp"を使ってC++関数を呼び出す必要がありますか?
バイナリ
エントリポイントで111で終わるテーブル内の数値のカウントを与えるプログラム:
#include <iostream>
#include <cstdlib>
extern "C" auto _start(void *, void *)->void;
auto print_msg(char *msg) {
std::cout << msg;
}
auto print_int(uint64_t val) {
std::cout << val;
}
auto main()->int {
_start(print_int, print_msg);
std::cout << std::endl;
system("pause");
}
アセンブリ:
.const
_tab dw 65535, 61951, 61949, 61925, 61927, 61734, 61735, 61728
_LENGTH = ($ - _tab)/2
_msg_1 db 'There are ', 0
_msg_2 db ' numbers ending with 111 in binary!', 0
.code
_start proc
push r15
push r14
sub rsp, 32 + 16
mov r14, rcx
mov r15, rdx
xor rcx, rcx
xor r9, r9
lea r8, _tab
_LOOP: movzx rax, word ptr [r8]
and rax, 111b
cmp rax, 111b
jz _INC
jmp _END_IF
_INC: inc rcx
_END_IF: inc r9
add r8, 2
cmp r9, _LENGTH
jne _LOOP
mov [rsp + 32], rcx
lea rcx, _msg_1
call r15
mov rcx, [rsp + 32]
sub rsp, 8
call r14
add rsp, 8
lea rcx, _msg_2
call r15
add rsp, 32 + 16
pop r14
pop r15
ret
_start endp
end
私がコメントする場合」 sub rsp、8 "、" add rsp、8 "を呼び出すと、プログラムはすぐにクラッシュします私はなぜそれが起こるのか知りたいのですが、また、 "mov rspx32"、 "rcx"、 "mov rcx rspx32"を "push rcx"と " popのrcx "の場合、出力はゴミになります。私はそれについても興味があります
関数 '_start'を呼び出さないでください。これはエントリポイントのデフォルトの名前です(少なくともLinuxでは)。独自の '_start'を定義するプログラムは、標準のCRTスタートアップコードをリンクせず、' _start'は返すことのできる関数でもありません。それは単なるエントリーポイントです。 TL:DR: '_start'は多くの読者にとって混乱している関数名です。 –