私は本を読んでいます (アセンブリ言語のステップ バイ ステップ、 Jeff Duntemann による Linux でのプログラミング) で、引数を表示するこのプログラムを変更して、代わりに環境変数を表示しようとしています。私はこれまでに教えられたもの(Cなし)のみを使用しようとしています。プログラムに環境変数を出力させましたが、持っている数を数えて即時を使用した後でのみ、明らかに満足のいくものではありませんでした。ここに私が持っているものがあります:
global _start ; Linker needs this to find the entry point!
_start:
nop ; This no-op keeps gdb happy...
mov ebp,esp ; Save the initial stack pointer in EBP
; Copy the command line argument count from the stack and validate it:
cmp dword [ebp],MAXARGS ; See if the arg count exceeds MAXARGS
ja Error ; If so, exit with an error message
; Here we calculate argument lengths and store lengths in table ArgLens:
xor eax,eax ; Searching for 0, so clear AL to 0
xor ebx,ebx ; Stack address offset starts at 0
ScanOne:
mov ecx,0000ffffh ; Limit search to 65535 bytes max
mov edi,dword [ebp+16+ebx*4] ; Put address of string to search in EDI
mov edx,edi ; Copy starting address into EDX
cld ; Set search direction to up-memory
repne scasb ; Search for null (0 char) in string at edi
jnz Error ; REPNE SCASB ended without finding AL
mov byte [edi-1],10 ; Store an EOL where the null used to be
sub edi,edx ; Subtract position of 0 from start address
mov dword [ArgLens+ebx*4],edi ; Put length of arg into table
inc ebx ; Add 1 to argument counter
cmp ebx,44; See if arg counter exceeds argument count
jb ScanOne ; If not, loop back and do another one
; Display all arguments to stdout:
xor esi,esi ; Start (for table addressing reasons) at 0
Showem:
mov ecx,[ebp+16+esi*4] ; Pass offset of the message
mov eax,4 ; Specify sys_write call
mov ebx,1 ; Specify File Descriptor 1: Standard Output
mov edx,[ArgLens+esi*4] ; Pass the length of the message
int 80H ; Make kernel call
inc esi ; Increment the argument counter
cmp esi,44 ; See if we've displayed all the arguments
jb Showem ; If not, loop back and do another
jmp Exit ; We're done! Let's pack it in!
と の両方で、変位を最初の null ポインターを超えて最初の環境変数 ( [ebp+4+ebx*4] > [ebp+16+ebx*4]
) に移動しました。私が持っている環境変数の数(44)と比較すると、セグメンテーション違反なしで問題なく出力されます.45と比較すると、セグメンテーション違反のみが発生します。ScanOne
Showem
ポインターを使用してゼロと比較しようとしました(nullポインターを検索して):cmp dword [ebp+16+ebx*4],0h
しかし、それはセグメンテーション違反を返すだけです。スタック内の最後の環境変数の後にヌルポインターが来ると確信していますが、それ以上は何もしないようです。
どこが間違っていますか?