[ARM] tst 명령어를 실행하면 ARM CPSR 레지스터가 어떻게 변경될까?

AustinKim의 이미지

tst 명령어는 연산자와 비연산자 사이 AND 비트 연산을 수행합니다.

AND 비트 연산 결과에 따라 CPSR 레지스터 Z 비트는 다음과 같이 변경됩니다.

Z: 0 ( AND 비트 연산 결과가 1인 경우)
Z: 1 ( AND 비트 연산 결과가 0인 경우)

tst 명령어가 위와 같이 동작하는지 증명하기 위해 T32 디버거를 실행해 보겠습니다.
다음 화면은 tst 명령어를 실행하기 직전입니다.

 
NSR:80107E6C|ret_to_user_from_irq:        ldr     r2,[r9,#0x8]
NSR:80107E70|                             cmp     r2,#0x7F000000   ; r2,#2130706432
NSR:80107E74|                             blne    0x8010B5FC       ; addr_limit_check_failed
NSR:80107E78|                             ldr     r1,[r9]
NSR:80107E7C|_____________________________tst_____r1,#0x0F_________;_r1,#15
NSR:80107E80|                             bne     0x80107E48       ; slow_work_pending
NSR:80107E84|no_work_pending:             bl      0x801E9CE8       ; trace_hardirqs_on
 
[레지스터 세트]
N _  R0          0  R8          0   
Z Z  R1          2  R9          0
C _  R2          0  R10         0
V _  R3          0  R11         0
Q _  R4   00020000  R12         0
     R5          0  R13  C000D000
0 _  R6          0  R14         0
1 _  R7          0  PC   80107E7C
2 _  SPSR       10  CPSR 400001D3
 
R1가 2(이진수 10)이니 0xF와 AND 비트 연산을 하면 1이 될 것입니다.
<code>
1111 (0xF)
  10 (2: R1) 
----------------
   1 (연산 결과)

다음은 "tst r1,#0x0F" 명령어를 실행한 후 결과입니다.

NSR:80107E6C|ret_to_user_from_irq:        ldr     r2,[r9,#0x8]
NSR:80107E70|                             cmp     r2,#0x7F000000   ; r2,#2130706432
NSR:80107E74|                             blne    0x8010B5FC       ; addr_limit_check_failed
NSR:80107E78|                             ldr     r1,[r9]
NSR:80107E7C|                             tst     r1,#0x0F         ; r1,#15
NSR:80107E80|_____________________________bne_____0x80107E48_______;_slow_work_pending
NSR:80107E84|no_work_pending:             bl      0x801E9CE8       ; trace_hardirqs_on
 
[레지스터 세트]
N _  R0          0  R8          0   
Z _  R1          2  R9          0
C _  R2          0  R10         0
V _  R3          0  R11         0
Q _  R4   00020000  R12         0
     R5          0  R13  C000D000
0 _  R6          0  R14         0
1 _  R7          0  PC   80107E80
2 _  SPSR       10  CPSR     01D3

여기서 눈을 크게 뜨고 봐야 할 중요한 정보는 ARM CPSR 레지스터입니다.
CPSR 레지스터가 0x1D3으로 변경됐습니다. CPSR 레지스터 Z 비트가 0이란 이야기입니다.

bne 명령어는 'branch not equal'이란 뜻입니다. Z가 0이면 브랜치하겠다는 의미입니다.

bne 0x80107E48 ;slow_work_pending

CPSR 레지스터 Z 비트가 0이니 slow_work_pending 레이블로 브랜치 할 것입니다.

NSR:80107E80|_____________________________bne_____0x80107E48_______;_slow_work_pending

이 결과를 예상하면서 위 "bne 0x80107E48 ;slow_work_pending" 코드를 실행하니
slow_work_pending 레이블로 브랜치했습니다.

NSR:80107E48|E1A0000D__slow_work_pending:__cpy_____r0,r13
NSR:80107E4C|E1A02008                      cpy     r2,r8
NSR:80107E50|EB000D82                      bl      0x8010B460       ; do_work_pending
NSR:80107E54|E3500000                      cmp     r0,#0x0          ; r0,#0
NSR:80107E58|0A000009                      beq     0x80107E84       ; no_work_pending
NSR:80107E5C|B3A07000                      movlt   r7,#0x0          ; r7,#0
NSR:80107E60|E89D007F                      ldm     r13,{r0-r6}
NSR:80107E64|EA000032                      b       0x80107F34       ; local_restart

이번엔 r1 레지스터가 0x1000 일 때 tst 명령어가 어떤 동작을 하는지 확인해봅시다.

NSR:80107E6C|ret_to_user_from_irq:        ldr     r2,[r9,#0x8]
NSR:80107E70|                             cmp     r2,#0x7F000000   ; r2,#2130706432
NSR:80107E74|                             blne    0x8010B5FC       ; addr_limit_check_failed
NSR:80107E78|                             ldr     r1,[r9]
NSR:80107E7C|_____________________________tst_____r1,#0x0F_________;_r1,#15
NSR:80107E80|                             bne     0x80107E48       ; slow_work_pending
NSR:80107E84|no_work_pending:             bl      0x801E9CE8       ; trace_hardirqs_on
 
[레지스터 세트]
N _  R0          0  R8          0   
Z _  R1       1000  R9          0
C _  R2          0  R10         0
V _  R3          0  R11         0
Q _  R4   00020000  R12         0
     R5          0  R13  C000D000
0 _  R6          0  R14         0
1 _  R7          0  PC   80107E7C
2 _  SPSR       10  CPSR     01D3

위 명령어를 실행하기 전 CPSR 레지스터는 0x1D3이고 R1이 0x1000이란 사실을 기억합시다.
0xF는 이진수로 1111이고 R1가 저장하고 있는 0x1000은 이진수로 1111_0000_0000_0000 일 것입니다.

따라서 AND 비트 연산 결과는 0일 것입니다.

1111_0000_0000_0000  ( 0x1000: R1)
               1111  ( 0xF)
--------------------------------------------- AND 연산
	            0    (결과)

이 사실을 염두해두고 "tst r1,#0x0F" 명령어를 T32로 실행하겠습니다.
결과 화면은 다음과 같습니다.

NSR:80107E6C|ret_to_user_from_irq:        ldr     r2,[r9,#0x8]
NSR:80107E70|                             cmp     r2,#0x7F000000   ; r2,#2130706432
NSR:80107E74|                             blne    0x8010B5FC       ; addr_limit_check_failed
NSR:80107E78|                             ldr     r1,[r9]
NSR:80107E7C|                             tst     r1,#0x0F         ; r1,#15
NSR:80107E80|_____________________________bne_____0x80107E48_______;_slow_work_pending
NSR:80107E84|no_work_pending:             bl      0x801E9CE8       ; trace_hardirqs_on
 
[레지스터 세트]
N _  R0          0  R8          0   
Z Z  R1       1000  R9          0
C _  R2          0  R10         0
V _  R3          0  R11         0
Q _  R4   00020000  R12         0
     R5          0  R13  C000D000
0 _  R6          0  R14         0
1 _  R7          0  PC   80107E80
2 _  SPSR       10  CPSR 400001D3

CPSR 레지스터가 400001D3 이고 Z 비트가 1이 됐습니다.
레지스터 세트에서 Z 표시된 부분을 눈으로 따라가 보시기 바랍니다.
N _ R0 0 R8 0
Z Z R1 1000 R9 0

Z 필드가 켜져 있습니다.

Z 비트가 1인데 다음 bne 명령어를 실행하면 어떻게 실행할까요?

NSR:80107E80|_____________________________bne_____0x80107E48_______;_slow_work_pending
NSR:80107E84|no_work_pending:             bl      0x801E9CE8       ; trace_hardirqs_on

당연히 slow_work_pending 레이블로 브랜치하지 않고 80107E84 주소로 브랜치할 것입니다.

NSR:80107E6C|ret_to_user_from_irq:        ldr     r2,[r9,#0x8]
NSR:80107E70|                             cmp     r2,#0x7F000000   ; r2,#2130706432
NSR:80107E74|                             blne    0x8010B5FC       ; addr_limit_check_failed
NSR:80107E78|                             ldr     r1,[r9]
NSR:80107E7C|                             tst     r1,#0x0F         ; r1,#15
NSR:80107E80|                             bne     0x80107E48       ; slow_work_pending
NSR:80107E84|no_work_pending:_____________bl______0x801E9CE8_______;_trace_hardirqs_on

(개인블로그)
http://rousalome.egloos.com

Forums: 

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.