2010-11-10 34 views
5

Tôi đang cố gắng để hiểu một mã nhỏ:Có bất kỳ giá trị mặc định nào cho thanh ghi không?

jg 0x00000047 
dec esp 
inc esi 
add [ecx],eax 

giá trị của eax là gì? Đây là bốn câu đầu tiên của chương trình và tôi không biết nếu có một giá trị mặc định hoặc nếu các câu trước đó thêm một cái gì đó để eax.

OS của tôi là Linux và thực thi được biên soạn bởi gcc4.3 từ một mã nguồn C (gcc file.c exec)

+1

Không phải 'is', nhưng' là'. – leppie

+0

Nếu bạn cung cấp một số thông tin về nền tảng của mình (OS, định dạng có thể thực thi được), tôi chắc chắn ai đó có thể cho bạn biết những gì 'eax' được đặt ở điểm vào chương trình. – Edmund

+0

Đã chỉnh sửa, cảm ơn bạn đã đề xuất. –

Trả lời

3

Một số hướng dẫn ngầm cập nhật sổ đăng ký, ngay cả khi đích đến không được liệt kê rõ ràng trong mã. Một số ví dụ:

  • cpuid lợi nhuận giá trị trong eax, ebx, ecx và edx
  • loop suất này ECX
  • rep hướng dẫn chuỗi thay đổi ecx, edi và esi
  • rdmsr thay đổi eax và edx
  • muldiv thay đổi eax và edx

Và có nhiều ví dụ khác.

Bạn không thể giả định chỉ bằng cách thấy rằng eax không được liệt kê trong mã mà nó không bị thay đổi.

Thậm chí giả sử bạn biết rằng những thanh ghi bị ảnh hưởng bởi đó hướng dẫn, thời gian duy nhất bạn có bất kỳ đảm bảo cho một giá trị là:

  • sau khi một lệnh mà bạn biết sẽ cập nhật nó
  • ngay sau khi phần cứng reset

Bất kỳ lúc nào khác, bạn không bao giờ có thể đưa ra các giả định về các giá trị.

+0

Vì vậy, chúng tôi sẽ nói rằng eax có một giá trị ngẫu nhiên (ít nhất là ngẫu nhiên đối với tôi)? –

+1

@Vaul: vâng, chúng tôi sẽ –

5

Phụ thuộc vào nền tảng, ngôn ngữ và/hoặc gọi điện thoại hội nghị. Nhưng vâng, mã trước đây thường nên đặt EAX thành một số giá trị. EAX là một trong những sổ đăng ký được sửa đổi thường xuyên đến nỗi nó không được sử dụng bình thường để giữ các thứ xung quanh.

Hướng dẫn trông khá là ngẫu nhiên. Đặc biệt, "dec esp" thường là một không-không lớn, vì ngăn xếp phải luôn được liên kết dword. Bạn có chắc đây là mã thực tế không? Các byte lệnh dịch thành "\ x7fELF" nếu tôi dịch đúng, điều này gợi ý với tôi rằng đây chỉ là các byte tiêu đề của một chương trình Linux, không phải là các byte mã thực tế.

+0

Tôi tháo rời một mã chương trình nhỏ được viết bởi tôi trong C cố gắng để hiểu mã asm, tôi giả sử rằng họ không phải là hướng dẫn ngẫu nhiên. Như tôi nói không có câu trước, vì vậy eax có thể có một giá trị ngẫu nhiên. Cảm ơn bạn. –

+0

Bạn tháo mã như thế nào? Hãy nhớ rằng một tệp thực thi hiếm khi chỉ là mã thô. (Định dạng duy nhất tôi biết là các tệp .com, và những định dạng này đã lỗi thời từ 10 năm trở lên.) Có một định dạng phức tạp hoàn toàn để thực thi trong hầu hết các hệ điều hành 32 bit. – cHao

+0

Sử dụng x86dis, có được không? –

2

Dường như mã này không hợp lệ. Bạn có chắc đó không phải là văn bản không?

Giải mã nó như 32bit x86 cung cấp cho chuỗi ELF:

00: 7F 45 // 0x7F E 
02: 4C  // L 
03: 46  // F 
04: 01 01 // ?? ?? 

Thử mở file dưới dạng file ELF và không phải là chỉ nhị phân.

4

Tôi nghĩ những gì bạn đang thực sự hỏi là calling convention, mô tả cách các chương trình con trong một chương trình truyền thông tin cho nhau và cách hệ điều hành chuyển thông tin đến chương trình. . Ví dụ, cdecl calling convention on the x86, được sử dụng bởi hầu hết các trình biên dịch C, nói rằng khi một hàm trả về, giá trị trả về đi vào thanh ghi eax. Vì vậy, nếu bạn có chức năng int foo(), bạn biết rằng sau khi foo thực thi mã vạch ret của mình, eax sẽ chứa mã đó foo được trả về.

Ngược lại, bộ xử lý PowerPC (thường) có (ít nhất) 32 thanh ghi, đơn giản là r0, r1, ... r31. The AIX calling convention cho chip này nói rằng con trỏ ngăn xếp đi vào r1, các tham số chức năng đó được truyền từ r3 đến r11, mà các giá trị trả về sẽ quay lại trên r3, v.v.

Điều quan trọng cần nhớ là quy ước gọi là loại thỏa thuận giữa các chức năng trong chương trình hoặc giữa các thư viện. Nó không phải là một phần của phần cứng, hoặc một luật, và thường có nhiều quy ước gọi điện khác nhau có thể được sử dụng trên một nền tảng. Đây là lý do tại sao đôi khi bạn sẽ thấy mã như

struct CFoo { void __stdcall method(); }; 

Đó là một chỉ dẫn để MSVC, mà thường thích sử dụng quy ước fastcall, nói cho nó để sử dụng một quy ước khác nhau cho rằng một trong những chức năng. Điều này quan trọng nếu ví dụ: chức năng được xác định trong thư viện được xây dựng bởi một số trình biên dịch khác sử dụng stdcall thay thế.

Khi chúng ta nói về cách hệ điều hành chuyển thông tin đến một chương trình (hoặc phần cứng đến hệ điều hành), chúng ta thường gọi nó là ABI thay vì quy ước gọi điện. Vì vậy, trong trường hợp của chương trình của bạn, nó đã được viết giả định rằng hệ điều hành sẽ vượt qua nó một số thông tin cụ thể về eax. Giả thiết đó sẽ đặc biệt đối với hệ điều hành, trình biên dịch và thậm chí cả chương trình riêng lẻ.

+0

Cảm ơn bạn rất nhiều, điều này mang lại cho tôi một điểm tốt để hiểu ASM. –

Các vấn đề liên quan