어셈 질문(leal, sarl, shrl 등)

시지프스의 이미지

int c = -33;
c /= 2;

를 gcc로 컴파일 했더니 다음과 같이 나왔습니다.
	movl	$-33, -4(%ebp)
	movl	-4(%ebp), %edx
	movl	%edx, %eax
	sarl	$31, %eax
	shrl	$31, %eax
	leal	(%edx,%eax), %eax
	sarl	%eax
	movl	%eax, -4(%ebp)

0과 비교해서 음수면 1을 더하고 양수면 넘어가야 되는데, branch하는 게 싫어서 이렇게 한 것 같습니다만...
sarl $31, %eax
shrl $31, %eax
이렇게 하는 것은 그냥 shrl $31, %eax와 뭐가 다른가요? %eax가 양수면 0, 음수면 1을 남기려는 것 아닌가요?

그리고 leal이 무엇인지 궁금하네요.
조인시 위키에는

Quote:

eal M, I/R/M O/S/Z/A/C
다른 명령어들 처럼 특정 메모리 위치에 있는 값을 읽는 것이 아니라 메모리 주소를 읽어들이게 된다. 예를 들어 leal 5(%ebp, %ecx, 1), %eax는 5+%ebp+1*%ecx로 계산한 주소 값의 메모리를 읽어서 %eax에 저장한다.

라고 되어 있는데, 메모리에 저장된 것이 아무것도 없으니 이건 아닌 것 같고, 어셈 러브에 가보니 이런 글이 있는데, 여기서는 이렇다고 하네요.
Quote:

leal -4(%ebp), %eax // 이것은 이런 뜻임 movl $-4, %eax ; add %ebp, %eax
그런데
leal datablk, %ebx //이것은 이런 뜻임 void *ebx = (void *) &datablk;

아무튼 이것저것 읽어봤는데 전혀 이해가 안 되고 있습니다.
그리고 leal을 쓰는 것이 add를 쓰는 것보다 빠르다는 말이 있는데 그건 왜 그렇죠? add도 한 사이클이면 충분하지 않나요.

시지프스의 이미지

int d;
scanf("%d",&d);
d /= 2;
return d;

이런식으로 하고 최적화 옵션을 주니 결과가 달라지네요.
movl	-4(%ebp), %eax
movl	%eax, %edx
shrl	$31, %edx
addl	%edx, %eax
sarl	%eax
movl	%eax, -4(%ebp)

결론은 컴파일러 마음이군요.
아직 leal은 이해하지 못하고 있습니다. 설명 좀 해주세요.

begin{signature}
THIS IS SPARTA!!!!!n.
end{signature}

grassman의 이미지

lea 명령은 해당 주소를 얻는 연산이기 때문에 레지스터를 이용하여 간접 주소로 접근할 때는 레지스터의 값을 계산한 결과와 동일하게 됩니다. lea를 사용하면 CPU의 주소 계산 기능을 이용하여 특수한 수에 대한 곱셈 및 덧셈을 할 수 있습니다. 그것도 곱셈 명령을 사용하지 않으면서 clock cycle도 적게 소모하고 pipeline의 효과도 볼 수 있기 때문에 i486 이후부터 널리 사용되었습니다.

예를 들어 eax = eax * 5라는 계산을 해야 한다면 leal (%eax, %eax, 4), %eax이라고 하면 됩니다. eax + eax * 4 == eax * 5이니까요.

그리고 위의 최적화는 나눗셈의 비용이 크기 때문에 곱셈과 shift 연산의 형태로 치환한 것으로 보입니다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.